Saying no is part of our job

Author: Valeriano Sandrucci 

A Professional Responsibility

In software development, saying no is not an act of closure. It is an act of responsibility.

We would like to always say yes. It is natural: projects are the engine of our business, and accepting them is almost always the easiest path, sometimes even the most profitable one in the short term. But it is not always the right thing to do.

In the world of technical consulting there is a widespread temptation: to accommodate. One can accommodate a still fragile idea, a roadmap built on unverified assumptions, a technical conviction that does not withstand deeper analysis, or the request to add a temporary solution to a system that actually needs to be rethought.

Accepting under these conditions requires little effort. Refusing or reframing requires competence, method, and a certain idea of what engineering actually means.

When Uncertainty Is Ignored

Many software initiatives are born from genuine enthusiasm. They may originate from a business intuition, from an operational process that no longer scales, or from frustration toward a legacy system.

The problem is rarely the initial idea itself. The critical point concerns how deeply the surrounding uncertainty has been explored.

We have seen proposals for new digital products based on technical assumptions that were never validated, reengineering efforts considered superficial that actually concealed deep structural fragilities, integrations between platforms assumed to be simple but architecturally incompatible, and roadmaps built on incomplete specifications with the implicit expectation that problems would somehow be solved later.

In situations like these, the idea itself is not the primary risk. The risk comes from treating uncertainty as if it did not exist.

When uncertainty is ignored, the project appears to start quickly. Then it slows down, becomes more complicated, and generates tension. At that point, the discussion stops being about technical choices and shifts toward responsibility.

The Yes That Avoids Friction

In the short term, there is a very effective behavioral model: minimizing decision-making friction. In software development, this attitude manifests itself through reassuring and immediate answers, the promise to adapt to any constraint, and the willingness to confirm delivery dates without a real verification of the technical conditions.

At first, this approach works. The client feels reassured and the project begins with enthusiasm.

Difficulties emerge when the system’s real complexity exceeds what had been imagined. Integrations do not turn out to be straightforward, requirements evolve, and years of accumulated technical debt prevent shortcuts. Under these conditions, the initial consensus quickly turns into tension: scope grows, budget shrinks, and trust between the parties deteriorates.

Accepting without discussion may appear collaborative. In reality, it simply moves the conflict further into the future.

What It Means to Say No

In our work, saying no does not mean blocking an initiative. It means reframing it in a sustainable way. It does not deny the possibility of doing something. It asks that it be done consciously.

Saying no may mean:

“We cannot estimate this accurately until we analyze the integration.”

“This system cannot support incremental evolution without structural intervention.”

“If we keep this budget constraint, we need to reduce the objective.”

“Before committing to a full delivery, a targeted technical analysis is necessary.”

“This decision involves a trade-off that needs to be made explicit.”

These positions do not deny the possibility of carrying out the project. They simply ask that it be approached with greater awareness.

Software almost never fails because people are unable to write code. It fails because uncertainty was not governed.

Reducing Uncertainty Before Commitment

A mature project does not begin with all the answers. It begins with the right questions.

When the objective is still poorly defined, exploration is necessary. When the budget is limited, priorities must be selected carefully. When technical risk is high, it is useful to validate certain assumptions before committing to full development. In more stable contexts, by contrast, it makes sense to focus directly on execution.

Saying no often means proposing a different sequence: first clarify the critical uncertainty, then validate the technical assumptions and the main trade-offs, and only afterward increase the level of economic and project commitment.

This approach may appear slower at first. In reality, it reduces the probability of investing months of work in a direction that will not hold up over time.

The Most Difficult Noes

The most difficult refusals are almost never technical. They are relational.

It means explaining to an enthusiastic entrepreneur that an idea requires validation before full development, or telling an IT manager that a system cannot simply be “fixed” without architectural reconsideration. In other cases, it means recognizing that a date decided in advance is incompatible with the level of remaining uncertainty.

These are uncomfortable conversations, but they are also the ones that build trust over time. Trust does not emerge from the absence of friction, but from clarity regarding limits, risks, and available alternatives.

A No That Protects Both Sides

There is a common belief that saying no means losing opportunities. In the short term, that may happen. In the long term, the opposite is often true.

Accepting a project built on fragile assumptions exposes everyone involved. The client risks investing resources inefficiently, the supplier ends up working in a context of continuous conflict, and the technical team operates under conditions of constant ambiguity.

A justified refusal can prevent a yes that would ultimately generate frustration. Some collaborations begin with a “not yet” and become solid projects only after the context has been clarified more effectively. In other cases, the decision not to proceed remains the correct one.

Not every initiative needs to become a project, and not every project needs to start immediately.

Productive Capacity and Responsibility

There is a substantial difference between providing productive capacity and taking responsibility for the outcome.

When value is measured exclusively in billable hours, accepting is almost always the easiest choice. When value is instead connected to the sustainability of the result, the scope must be negotiated, uncertainty must be explored, and risks must be declared.

This kind of work also requires maturity from the other side of the table. It requires stakeholders willing to discuss priorities, to give up something in the short term, and to accept that not everything can be estimated before it is understood.

A Sign of Partnership

A technical partner does not simply execute. A technical partner participates in decisions.

Participating in decisions also means pointing out limits, highlighting risks, and proposing more sustainable alternatives. The goal is not to maximize the number of projects started, but to increase the probability that the projects that do start will continue to work over time.

And that, inevitably, includes some noes.

  • No to arbitrary timelines.
  • No to unvalidated specifications.
  • No to architectural shortcuts that generate structural debt.
  • No to initiatives where uncertainty is denied instead of governed.

Every no is an act of alignment with reality.

Saying no is not a form of closure. It is an investment in the quality of decisions.

Author: Valeriano Sandrucci 

Back to the index