{"record":{"id":"9f1e1ed52fcd7598","repo":"langgenius/dify","slug":"snippet-not-found","errorCode":null,"errorMessage":"Snippet not found","messagePattern":"Snippet not found","errorType":"http","errorClass":"NotFound","httpStatus":404,"severity":"error","filePath":"api/controllers/console/agent/composer.py","lineNumber":291,"sourceCode":"            WorkflowAgentComposerResponse,\n            AgentComposerService.save_workflow_composer(\n                session=session,\n                tenant_id=tenant_id,\n                app_id=app_model.id,\n                node_id=node_id,\n                account_id=account_id,\n                payload=req_data,\n            ),\n        )\n\n\ndef _require_snippet_app_id(*, session: Session, tenant_id: str, snippet_id: UUID) -> str:\n    snippet = SnippetService(session=session).get_snippet_by_id(\n        snippet_id=str(snippet_id),  # pyrefly: ignore[unnecessary-type-conversion]\n        tenant_id=tenant_id,\n    )\n    if snippet is None:\n        raise NotFound(\"Snippet not found\")\n    return snippet.id\n\n\n@console_ns.route(\"/snippets/<uuid:snippet_id>/workflows/draft/nodes/<string:node_id>/agent-composer\")\nclass SnippetAgentComposerApi(Resource):\n    @console_ns.response(200, \"Snippet agent composer state\", console_ns.models[WorkflowAgentComposerResponse.__name__])\n    @console_ns.doc(params=query_params_from_model(WorkflowAgentComposerQuery))\n    @setup_required\n    @login_required\n    @account_initialization_required\n    @with_current_user_id\n    @with_current_tenant_id\n    @with_session\n    @model_validate(WorkflowAgentComposerQuery)\n    def get(\n        self,\n        req_data: WorkflowAgentComposerQuery,\n        session: Session,","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/api/controllers/console/agent/composer.py#L273-L309","documentation":" werkzeug NotFound (HTTP 404) from _require_snippet_app_id: SnippetService.get_snippet_by_id returned None for the given snippet_id under the current tenant. The composer endpoint resolves snippet-scoped workflow nodes and must translate the snippet into an app context; no snippet means no app to operate on.","triggerScenarios":"Calling /console/snippets/<snippet_id>/workflows/draft/nodes/<node_id>/agent-composer (GET or save) with a snippet_id that does not exist or belongs to a different tenant. Also hit when a snippet was deleted between the workflow editor loading and the composer save.","commonSituations":"Stale workflow editor holding a reference to a deleted snippet; cross-tenant access attempt; snippet_id copied incorrectly; concurrency where one user deletes a shared snippet while another edits its composer.","solutions":["Reload the snippet list in the console to confirm the snippet still exists for your tenant.","Ensure the snippet_id in the URL is the current one (not a stale id from a prior session).","If the snippet was deleted intentionally, discard the local composer state and start from an existing snippet.","Check tenant membership of the calling account for the snippet's owning tenant."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"def snippet_exists(session, tenant_id: str, snippet_id: str) -> bool:\n    return SnippetService(session=session).get_snippet_by_id(\n        snippet_id=snippet_id, tenant_id=tenant_id\n    ) is not None","typeGuard":null,"tryCatchPattern":"from werkzeug.exceptions import NotFound\n\ntry:\n    resp = client.get(composer_url)\nexcept NotFound as exc:\n    if 'Snippet not found' in str(exc):\n        reload_snippet_list()\n    raise","preventionTips":["Reload the snippet list before editing a composer that has been open a while.","Discard composer state when the backing snippet is deleted.","Confirm tenant membership for shared snippets before editing."],"tags":["snippet","agent-composer","not-found","tenant-scope"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}