langgenius/dify · error · NotFound

Snippet not found

Error message

Snippet not found

What it means

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.

Source

Thrown at api/controllers/console/agent/composer.py:291

            WorkflowAgentComposerResponse,
            AgentComposerService.save_workflow_composer(
                session=session,
                tenant_id=tenant_id,
                app_id=app_model.id,
                node_id=node_id,
                account_id=account_id,
                payload=req_data,
            ),
        )


def _require_snippet_app_id(*, session: Session, tenant_id: str, snippet_id: UUID) -> str:
    snippet = SnippetService(session=session).get_snippet_by_id(
        snippet_id=str(snippet_id),  # pyrefly: ignore[unnecessary-type-conversion]
        tenant_id=tenant_id,
    )
    if snippet is None:
        raise NotFound("Snippet not found")
    return snippet.id


@console_ns.route("/snippets/<uuid:snippet_id>/workflows/draft/nodes/<string:node_id>/agent-composer")
class SnippetAgentComposerApi(Resource):
    @console_ns.response(200, "Snippet agent composer state", console_ns.models[WorkflowAgentComposerResponse.__name__])
    @console_ns.doc(params=query_params_from_model(WorkflowAgentComposerQuery))
    @setup_required
    @login_required
    @account_initialization_required
    @with_current_user_id
    @with_current_tenant_id
    @with_session
    @model_validate(WorkflowAgentComposerQuery)
    def get(
        self,
        req_data: WorkflowAgentComposerQuery,
        session: Session,

View on GitHub (pinned to ef8544b173)

Solutions

  1. Reload the snippet list in the console to confirm the snippet still exists for your tenant.
  2. Ensure the snippet_id in the URL is the current one (not a stale id from a prior session).
  3. If the snippet was deleted intentionally, discard the local composer state and start from an existing snippet.
  4. Check tenant membership of the calling account for the snippet's owning tenant.
Defensive patterns

Strategy: validation

Validate before calling

def snippet_exists(session, tenant_id: str, snippet_id: str) -> bool:
    return SnippetService(session=session).get_snippet_by_id(
        snippet_id=snippet_id, tenant_id=tenant_id
    ) is not None

Try / catch

from werkzeug.exceptions import NotFound

try:
    resp = client.get(composer_url)
except NotFound as exc:
    if 'Snippet not found' in str(exc):
        reload_snippet_list()
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/9f1e1ed52fcd7598. Report an issue: GitHub.