Fission-AI/OpenSpec · error · Error

Change " " has no proposal.md yet. Run "openspec status…

Error message

Change "${changeName}" has no proposal.md yet. Run "openspec status --change ${changeName}" to see which artifact comes next.

What it means

The change directory exists but has no proposal.md, which the show command was asked to display. This is normal for freshly scaffolded changes (only .openspec.yaml) or custom schemas without a proposal artifact; the message distinguishes missing-artifact from missing-change.

Solutions

  1. Run openspec status --change <name> to see which artifact comes next
  2. Author the proposal.md artifact for the change
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/commands/change.ts:103 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of Fission-AI/OpenSpec@6926ccb18a (2026-08-25). Data as JSON: /api/errors/0ec9abdb9590d756. Report an issue: GitHub.

Appendix: source

Thrown at src/commands/change.ts:103

    if (!isChangeDirectoryName(changesPath, changeDir)) {
      throw new Error(`Change "${changeName}" not found at ${proposalPath}`);
    }

    try {
      await fs.access(proposalPath);
    } catch {
      // A change can exist without a proposal: `openspec new change` scaffolds
      // only .openspec.yaml, and a custom schema need not define a proposal
      // artifact. Say which of the two cases this is instead of reporting a
      // change that does exist as missing. A stray file under changes/ is not a
      // change, and naming it one would point the user at a `status --change`
      // call that cannot work.
      const isChangeDirectory = await fs
        .stat(changeDir)
        .then((stats) => stats.isDirectory())
        .catch(() => false);
      if (isChangeDirectory) {
        throw new Error(
          `Change "${changeName}" has no proposal.md yet. ` +
            `Run "openspec status --change ${changeName}" to see which artifact comes next.`
        );
      }
      throw new Error(`Change "${changeName}" not found at ${proposalPath}`);
    }
    FileSystemUtils.assertPathWithin(path.dirname(proposalPath), proposalPath);

    if (options?.json) {
      FileSystemUtils.assertPathWithin(changeDir, proposalPath);
      const jsonOutput = await this.converter.convertChangeToJson(proposalPath);

      if (options.requirementsOnly) {
        console.error('Flag --requirements-only is deprecated; use --deltas-only instead.');
      }

      const parsed: Change = JSON.parse(jsonOutput);
      FileSystemUtils.assertPathWithin(changeDir, proposalPath);

View on GitHub (pinned to 6926ccb18a)