astrid-runtime/astrid · error

specify the topic exactly once (positional OR --topic, not…

Error message

specify the topic exactly once (positional OR --topic, not both)

What it means

Defensive arm of resolve_topic: this is only reachable if both positional and --topic were supplied simultaneously, which clap's conflicts_with should already reject; it exists so the match is total if the parser config ever changes.

Solutions

  1. Supply the topic exactly once — either positional or via --topic
  2. Check for a duplicate flag injected by a wrapper script or alias
  3. If seen without duplicates, report a clap conflicts_with regression
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/astrid-emit/src/lib.rs:147 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/69da227823fe9d00. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-emit/src/lib.rs:147

    ///
    /// `clap`'s `conflicts_with` already rejects supplying both, so the
    /// only failure this surfaces is supplying neither.
    ///
    /// # Errors
    ///
    /// Returns an error if no topic was supplied (neither positional
    /// nor `--topic`).
    pub fn resolve_topic(self) -> Result<String> {
        match (self.topic_positional, self.topic_flag) {
            (Some(t), None) | (None, Some(t)) => Ok(t),
            (None, None) => {
                anyhow::bail!("a topic is required (positional `<topic>` or `--topic <topic>`)")
            },
            // Unreachable in practice: clap's `conflicts_with` rejects
            // both-supplied before we get here. Kept exhaustive so the
            // match doesn't rely on that invariant silently.
            (Some(_), Some(_)) => {
                anyhow::bail!("specify the topic exactly once (positional OR --topic, not both)")
            },
        }
    }
}

/// Outcome of an [`emit`] call: what to print to stderr (if anything)
/// and which process exit code to return. The fixed `{"continue":true}`
/// stdout line is the caller's responsibility and is emitted
/// unconditionally regardless of this outcome.
#[derive(Debug)]
#[must_use]
pub struct Outcome {
    /// One-line diagnostic to write to stderr, or `None` on success.
    pub stderr: Option<String>,
    /// Process exit code — `0` on a successful publish, `1` otherwise.
    /// **Never** `2`.
    pub exit: ExitCode,
}

View on GitHub (pinned to affd8760f4)