EveryInc/compound-engineering-plugin · warning

Skipping ${targetPath}: existing unmanaged file (not overwri

Error message

Skipping ${targetPath}: existing unmanaged file (not overwritten)

What it means

Also from cleanupCurrentManagedFile in src/targets/opencode.ts: when the target exists as a regular file (not a symlink) but is NOT listed in the install manifest group (manifest?.groups[group] does not include entryName), it is treated as user-created/unmanaged and left untouched. The converter only deletes or overwrites files it can prove it installed previously.

Source

Thrown at src/targets/opencode.ts:41

// subsequent write -- writing through a preserved symlink would clobber the
// user's fork, which is worse than not overwriting at all). All four
// OpenCode artifact kinds (agents, commands, plugins, skills) are tracked in
// the install manifest's `groups` map, so the same ownership rule applies
// uniformly here rather than a symlink-only guard.
async function cleanupCurrentManagedFile(
  targetPath: string,
  manifest: ManagedInstallManifest | null,
  group: string,
  entryName: string,
): Promise<boolean> {
  const stat = await lstatOrNull(targetPath)
  if (!stat) return false
  if (stat.isSymbolicLink()) {
    console.warn(`Skipping ${targetPath}: existing user-managed symlink (not overwritten)`)
    return true
  }
  if (!manifest?.groups[group]?.includes(entryName)) {
    console.warn(`Skipping ${targetPath}: existing unmanaged file (not overwritten)`)
    return true
  }
  return false
}

async function mergeOpenCodeConfig(
  configPath: string,
  incoming: OpenCodeConfig,
): Promise<OpenCodeConfig> {
  if (!(await pathExists(configPath))) return incoming

  let existing: OpenCodeConfig
  try {
    existing = await readJson<OpenCodeConfig>(configPath)
  } catch {
    console.warn(
      `Warning: existing ${configPath} is not valid JSON. Writing plugin config without merging.`
    )

View on GitHub (pinned to c9c10f8c75)

Solutions

  1. If the file is yours, rename it or move it out of the managed directory so it no longer shadows the managed name.
  2. If you want the plugin's version, delete the unmanaged file (after backing up customizations) and re-run the install.
  3. If the manifest is stale/missing, remove the plugin's managed output and reinstall cleanly so the manifest is regenerated, then reapply customizations via config rather than editing generated files.
  4. Check the manifest to confirm the name: the entry must appear in manifest.groups[group] to be considered managed.

Example fix

// before: hand-made file blocks managed write
ls .opencode/agents/review.md  # not in manifest
// after
mv .opencode/agents/review.md .opencode/agents/review.local.md
bun run convert --to opencode
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync, readFileSync } from 'node:fs'
function isManifestManaged(manifestPath: string, group: string, entryName: string): boolean {
  if (!existsSync(manifestPath)) return false
  const m = JSON.parse(readFileSync(manifestPath, 'utf8'))
  return Array.isArray(m?.groups?.[group]) && m.groups[group].includes(entryName)
}
// if false for an existing file, the installer will treat it as unmanaged and skip it

Type guard

function hasGroupEntry(m: unknown, group: string, entry: string): m is { groups: Record<string, string[]> } {
  return typeof m === 'object' && m !== null &&
    Array.isArray((m as any).groups?.[group]) &&
    (m as any).groups[group].includes(entry)
}

Prevention

When it happens

Trigger: Running an OpenCode install/cleanup where a file exists at a managed location (e.g. .opencode/agents/foo.md) but the recorded install manifest for that group does not list it — e.g. the file was created by hand, by another tool, or the manifest was deleted/reset.

Common situations: Users hand-editing or hand-adding agent/command files alongside installed ones; manifest lost after a manual ~/.config or .opencode cleanup; switching plugin versions where the old manifest recorded different names; another agent platform's installer writing into .opencode.

Related errors


AI-assisted analysis of EveryInc/compound-engineering-plugin@c9c10f8c75 (2026-08-31). Data as JSON: /api/errors/c0bfc5e6b83a97b5. Report an issue: GitHub.