Feature Request or Bug? How to Tell Before Escalating to Engineering

The most expensive triage mistake is escalating a feature request as a bug, or dropping a code-actionable feature request as 'not a bug.' This post explains the structural distinction and what it means for your escalation workflow.

Watari Team
· 7 min read

Bugs and feature requests look identical in a Zendesk or Intercom queue. Both arrive as customer prose, both feel urgent, and both end up in front of an engineer if your triage process doesn't separate them first. The structural difference is exact: a bug has an expected-vs-actual delta and a repro path; a feature request does not. That single criterion, applied consistently, determines whether a ticket belongs in your Linear or Jira backlog, whether a Mapped Issue is created, and whether a draft PR is ever opened.

The Structural Difference Between a Bug and a Feature Request

A bug is defined by a gap between what the system was designed to do and what it actually does, and that gap is reproducible. Strip away the customer's emotional framing and what remains is a statement of the form: "When I do X, the system does Y, but it should do Z." If you cannot extract that triple from a ticket, you do not have a bug report.

A feature request is the absence of that triple. The customer wants something the system was never designed to do, or wants an existing capability to behave differently in a way that reflects a new design intent rather than a coding error. "I wish the dashboard loaded faster" and "Can you add a dark mode?" are feature requests. Neither has an expected-vs-actual delta because neither describes a violation of the current design.

This distinction is not subjective. It is structural, and it holds even when the customer's language is ambiguous. Consider these two tickets:

  • "When I export a report, the CSV always includes a header row I can't remove. I need it gone for my import tool."
  • "It would be great if the export page had more formatting options."

The first ticket has a specific behavior (header row always included), a specific expected behavior (an option to omit it), and an implied repro (export any report). It may or may not reflect a bug in the original design, but it is code-actionable: a specific change to existing code would satisfy it. The second ticket is open-ended. No specific code path is implicated. Routing it to engineering produces a design conversation, not a code change.

The triage error that floods engineering is treating both tickets identically.

What Makes a Feature Request Code-Actionable

A code-actionable feature request is a specific change to existing code that a developer could implement without a product design decision. The distinction matters because code-actionable feature requests are as actionable as bugs in the escalation workflow, even though they are not bugs.

Watari's extraction pipeline recognizes this category explicitly. When the extraction model processes a ticket from Zendesk or Intercom, it produces a structured record that includes an item_type field (bug or feature_request) and, for feature requests, an is_code_actionable flag. A feature request earns that flag when it points at a specific behavior in a specific part of the system that a developer could change without a design meeting. See the extraction stage docs for how these fields are populated from raw ticket text.

The practical consequence is significant. A code-actionable feature request clears both confidence gates (extraction confidence and code-location confidence) the same way a bug does. When it does, it becomes a Mapped Issue, the pipeline opens a draft PR, and the issue syncs to Linear or Jira exactly as a bug would. The billing meter also fires: see the Mapped Issue meter for why code-actionable feature requests are metered identically to bugs.

Open-ended requests never reach this stage. "I wish the UI were nicer" produces no code locations because no specific code path is implicated. The extraction model flags it as a non-code-actionable feature request, and the pipeline stops there. No Mapped Issue is created, no PR is opened, and no meter fires. The ticket remains in your support tool as an open item your team can address on its own schedule.

To make the distinction concrete, here are examples of each category:

Code-actionable feature requests (should escalate):

  • "Add a webhook payload field for the customer's account tier so our Zapier integration can filter by it."
  • "The CSV export should respect the column ordering I set in the table view, not always use the default."
  • "Allow the API token to be scoped to read-only so I can share it with a contractor."

Open-ended requests (should not escalate to engineering):

  • "The onboarding feels confusing. Can you make it simpler?"
  • "I wish there were more integrations."
  • "The UI could be more modern."

The first group names a specific behavior and a specific change. The second group names a feeling or a direction. The test is not the customer's intent but whether a developer could write a ticket in Jira or Linear with enough specificity to open a pull request.

How Structured Extraction Removes the Judgment Call

The triage error described above is so common because it requires the support lead to make a judgment call from prose, often under queue pressure, often without deep knowledge of the codebase. A ticket that reads "I can't get the export to work the way I need it" could be a bug, a code-actionable feature request, or an open-ended preference, and the correct classification depends on details buried in the conversation thread.

Structured extraction solves this by shifting the judgment from a human reading prose to a model reading the full ticket context, including the conversation thread, attachments, screenshots, and any screen recordings. When a ticket arrives from Zendesk or Intercom via webhook, Watari reads the entire conversation in order, including author labels and timestamps, and produces a structured record with:

  1. Item type (bug or feature_request).
  2. For feature requests: is_code_actionable (true or false).
  3. Severity, repro steps, and expected-vs-actual fields (for bugs).
  4. A confidence score for the extraction itself.

If the extraction confidence score does not clear the first gate, the ticket does not proceed. No Mapped Issue is created, no engineering time is consumed. If it does clear the gate, the second stage runs: the pipeline searches the codebase index (built by parsing your repository with tree-sitter and storing vector embeddings in a pgvector HNSW index) for the files and functions most likely implicated. Code-location confidence must also clear a second gate before a Mapped Issue is recorded.

Both gates must clear. A high-confidence extraction of a bug with no identifiable code location does not produce a Mapped Issue. A found code location that the extraction model is not confident about does not produce a Mapped Issue either. This two-gate structure means the support lead never needs to adjudicate borderline cases: the pipeline either produces a Mapped Issue ready for engineering review, or it does not.

The support lead's job in this model changes from "classify this ticket and decide whether to escalate" to "review Mapped Issues the pipeline surfaced and decide whether to accept or correct them." That is a narrower, higher-quality task.

What the Classification Decision Costs You

Misclassification has two failure modes, and both carry real costs.

Escalating a non-actionable request as a bug means an engineer receives a ticket with no repro path and no expected-vs-actual delta. They spend time diagnosing a non-issue, ask the support lead for clarification, wait for a response, and either close the ticket as "by design" or open a design conversation that should have happened in product review. Engineering time is expensive and this path wastes it at both ends.

Dropping a code-actionable feature request as "not a bug" means valid product signal is lost. If four customers independently ask for the same specific API change, each ticket classified as a non-bug means the pattern is invisible to engineering. No Mapped Issue is created, no duplicate detection runs, no draft PR is opened. The product misses a real need, and the customers eventually churn or find a workaround.

The structural definition given above prevents both failures:

  • If a ticket has no expected-vs-actual delta and no repro path, it is not a bug, and escalating it is a process error.
  • If a ticket has a specific, code-addressable request, it is code-actionable regardless of whether the customer used the word "bug."

The label the customer applies is irrelevant. "This is broken" and "I wish this worked differently" can describe identical behavior. The extraction stage reads the substance, not the label.

For teams operating at scale with Zendesk or Intercom, the volume makes manual classification unsustainable before long. When a hundred tickets arrive in a day, the support lead cannot spend ten minutes on each one assessing code-actionability. The extraction pipeline handles classification continuously, surfaces Mapped Issues to the dashboard, and routes them to Linear or Jira and the relevant CODEOWNERS via the draft PR, without a human in the loop for each ticket.

The human stays in the loop for the decisions that require judgment: accepting a Mapped Issue, reviewing a draft PR before it merges, and publishing a customer-facing RCA after a fix ships. Those are the decisions worth a human's time. Ticket classification is not.

FAQs

What is a code-actionable feature request? A code-actionable feature request is a customer request that names a specific behavior change in an existing system that a developer could implement without a product design decision. It differs from an open-ended request in that a specific code path is implicated and a pull request could plausibly address it.

Does a code-actionable feature request cost the same as a bug in Watari's billing? Yes. A code-actionable feature request that clears both confidence gates (extraction confidence and code-location confidence) is recorded as a Mapped Issue and metered identically to a bug. Open-ended feature requests that do not clear both gates are never metered. See the Mapped Issue meter for the exact qualification criteria.

How does Watari decide whether a feature request is code-actionable? The extraction model reads the full ticket conversation, including attachments and screenshots, and produces an is_code_actionable flag alongside the item type. A request earns the flag when the model identifies a specific behavior in a specific part of the system that a code change would address. The flag is also editable: a workspace owner or admin can override it before the ticket proceeds to code mapping. See AI behavior controls for the override workflow.

ShareX / TwitterLinkedIn

Get new posts in your inbox

One email when a new post lands. No spam. Unsubscribe in one click.

Frequently asked questions

What is a code-actionable feature request?
A code-actionable feature request is a customer request that names a specific behavior change in an existing system that a developer could implement without a product design decision. It differs from an open-ended request in that a specific code path is implicated and a pull request could plausibly address it.
Does a code-actionable feature request cost the same as a bug in Watari's billing?
Yes. A code-actionable feature request that clears both confidence gates (extraction confidence and code-location confidence) is recorded as a Mapped Issue and metered identically to a bug. Open-ended feature requests that do not clear both gates are never metered.
How does Watari decide whether a feature request is code-actionable?
The extraction model reads the full ticket conversation, including attachments and screenshots, and produces an is_code_actionable flag alongside the item type. A request earns the flag when the model identifies a specific behavior in a specific part of the system that a code change would address.
What is the structural difference between a bug and a feature request?
A bug has an expected-vs-actual delta and a reproducible path to trigger it. A feature request does not: it describes something the system was never designed to do, or a new design intent rather than a coding error. This distinction is structural, not a matter of the customer's framing or language.