Skip to content

archive refuses a change when openspec/changes is a symlink (regression since 1.8.0) #2050

Closed

Description

@Equasa

What happens

Since 1.8.0, openspec archive fails when the project's openspec/changes
directory is a symlink to a directory in another repository:

Error: Refusing to archive through a path outside the OpenSpec root: <repo>/openspec/changes

1.7.0 archives the same layout correctly. Still present in 1.14.1.

Why we use the layout

Several code repositories keep their specs and changes in one shared
documentation repository. Each code repository's openspec/changes and
openspec/specs are relative symlinks into it. openspec new change,
list and status follow the symlinks; only archive refuses.

Reproduce

mkdir -p docsrepo/modules/x/changes docsrepo/modules/x/specs modrepo/openspec
git -C docsrepo init -q; git -C modrepo init -q
ln -s ../../docsrepo/modules/x/changes modrepo/openspec/changes
ln -s ../../docsrepo/modules/x/specs modrepo/openspec/specs
cd modrepo
npx @fission-ai/openspec@1.14.1 new change probe
printf '## Why\n\nProbe.\n\n## What Changes\n\n- Probe.\n' > openspec/changes/probe/proposal.md
printf '## 1. Probe\n\n- [x] 1.1 Probe\n' > openspec/changes/probe/tasks.md
npx @fission-ai/openspec@1.14.1 archive probe --yes --skip-specs --no-validate
# Error: Refusing to archive through a path outside the OpenSpec root
npx @fission-ai/openspec@1.7.0 archive probe --yes --skip-specs --no-validate
# Archives to docsrepo/modules/x/changes/archive/<date>-probe

Expected

The guard protects against archiving outside the project. A symlink that
the project itself owns (openspec/changes, openspec/specs) is part of
the project's layout, so archive could resolve both sides with realpath
before comparing, and accept a target inside the resolved changes directory.

Workaround

We pin 1.7.0. On newer versions, archiving from a temporary openspec/
directory inside the documentation repository works.

Activity

  1. added a commit that references this issue on Oct 14, 2026
    90c95c2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions