{"record":{"id":"866f6402c94bceb1","repo":"Fission-AI/OpenSpec","slug":"template-artifact-template-for-artifact-ar","errorCode":null,"errorMessage":"Template '${artifact.template}' for artifact '${artifact.id}' points outside the schema templates directory","messagePattern":"Template '(.+?)' for artifact '(.+?)' points outside the schema templates directory","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/commands/workflow/templates.ts","lineNumber":81,"sourceCode":"      source = 'project';\n    } else if (isInsideDir(schemaDir, userSchemasDir)) {\n      source = 'user';\n    } else {\n      source = 'package';\n    }\n\n    const templatesDir = path.join(schemaDir, 'templates');\n    const templates: TemplateInfo[] = graph.getAllArtifacts().map((artifact) => {\n      const templatePath = path.join(templatesDir, artifact.template);\n      try {\n        FileSystemUtils.assertPathWithin(templatesDir, templatePath);\n        return {\n          artifactId: artifact.id,\n          templatePath: FileSystemUtils.canonicalizeExistingPath(templatePath),\n          source,\n        };\n      } catch {\n        throw new Error(\n          `Template '${artifact.template}' for artifact '${artifact.id}' points outside the schema templates directory`\n        );\n      }\n    });\n\n    spinner?.stop();\n\n    if (options.json) {\n      const output: Record<string, { path: string; source: string }> = {};\n      for (const t of templates) {\n        output[t.artifactId] = { path: t.templatePath, source: t.source };\n      }\n      console.log(JSON.stringify(output, null, 2));\n      return;\n    }\n\n    console.log(`Schema: ${schemaName}`);\n    console.log(`Source: ${source}`);","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/Fission-AI/OpenSpec/blob/6926ccb18afa4ff621112813e9968334576ee11a/src/commands/workflow/templates.ts#L63-L99","documentation":"Path-confinement guard in templatesCommand: the template filename declared for an artifact in the schema resolves outside the schema's templates directory (via FileSystemUtils.assertPathWithin). Indicates a malicious or malformed artifact.template entry in the schema definition.","triggerScenarios":"Thrown at src/commands/workflow/templates.ts:81 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Fix the template path in the schema's artifact definition to stay inside templates/","Remove the offending artifact or template declaration from the schema"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"6926ccb18afa4ff621112813e9968334576ee11a","analyzedAt":"2026-08-25T12:29:45.729Z","contentChangedAt":"2026-08-25T12:29:45.729Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}