Skip to content

flowctl: catalog status silently exits 0 with no output when an authorized name matches no live spec (misreads as no-access) #3253

Description

@jwhartley

1. Priority

Low - developer/agent UX. No incorrect data. The failure mode is a misleading empty result during investigation that led to a wrong conclusion (I decided I had no read grant when I was authorized and had simply passed a slightly wrong name).

2. Scope and prevalence

Any caller of flowctl catalog status <name> who passes a name they ARE authorized to read but which is not an exact live-spec name - e.g. a catalog prefix, or a task name missing a segment. Agents are especially prone: when mapping a Gazette/Mimir shard label to a catalog name, the shard path's trailing connector-image segment is part of the catalog name (materialize/acmeCo/my-mat/materialize-mongodb/<hash> -> catalog name acmeCo/my-mat/materialize-mongodb, not acmeCo/my-mat). Dropping that segment yields a name that is a valid, authorized prefix but not a spec.

3. Problem description

  • Expected: either the status prints, or a clear not-found signal (nonzero exit + a message naming the unresolved name).

  • Observed: flowctl catalog status <authorized-but-absent-name> exits 0 with no stdout and no stderr. This is indistinguishable from a successful run that happened to have empty status. Contrast with the unauthorized case, which is loud: a name under a prefix the caller cannot read errors with PermissionDenied: user is not authorized to access prefix or name '<name>' with required capability read and exits 1.

    So the tool already distinguishes authz failure clearly - but the "authorized, no such spec" case is silent. The consequence is backwards for a caller: because authz denial is loud, a silent empty result actually means "you ARE authorized, the name just didn't resolve" - yet nothing in the output says so, and it reads instead like masking / no access / no data.

  • Steps to reproduce (caller has read on acmeCo/):

    1. flowctl catalog status acmeCo/my-mat (prefix / missing trailing image segment) -> exit 0, no output.
    2. flowctl catalog status acmeCo/my-mat/materialize-mongodb (exact name) -> prints status.
    3. flowctl catalog status someTenantYouCannotRead/anything -> PermissionDenied ..., exit 1.
  • Impact: an agent (or a person) reads the case-1 silent empty as "RLS-masked / no grant / no data" and confabulates a root cause. In the investigation that surfaced this, that misread cost a full detour before the name was corrected.

4. Suggested direction (support, non-binding)

  • Primary: when the requested name(s) match zero live specs and the caller is authorized on the prefix, emit no live spec found matching "<name>" on stderr and exit nonzero. For multiple names, report resolved-vs-requested and name the misses (2 of 3 names matched; not found: acmeCo/my-mat). This alone would have stopped the misdiagnosis - zero of my names resolving is an obvious "check the name" signal.
  • The not-found message need not hedge about access for this case: authz denial is already its own distinct loud error (step 3), so a silent-then-not-found path unambiguously means authorized-but-absent. (A neutral "(it may not exist, or you may lack access)" is acceptable if the two are impractical to separate at that layer.)
  • Bonus (nice-to-have): because reaching the silent-empty path proves the caller IS authorized on the prefix, a sibling lookup scoped to that prefix is both safe (already authorized) and cheap, so a did you mean "acmeCo/my-mat/materialize-mongodb"? suggestion is most feasible in exactly the case that triggers this - a name that is a prefix of, or missing a segment from, a real spec.

5. References

Metadata

Metadata

Assignees

No one assigned

    Labels

    AXAgent Experience improvementsflowctlIssues related to the user facing CLI

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions