HumanSignal/label-studio · error · Http404

“%(path)s” does not exist

Error message

“%(path)s” does not exist

What it means

The static serve view raises Http404('“%(path)s” does not exist') when the resolved file (after optional webpack manifest asset resolution) does not exist on disk under document_root. This means the requested static asset is missing from the deployed static files.

Source

Thrown at label_studio/core/utils/static_serve.py:71

        document_root = "/dist/apps/labelstudio/"
        manifest_asset_prefix = "react-app"
        manifest_json = {"main.js": "/react-app/main.123456.js"}
        fullpath = Path(safe_join(document_root, "main.123456.js"))
    """
    path = posixpath.normpath(path).lstrip('/')
    fullpath = Path(safe_join(document_root, path))
    if fullpath.is_dir():
        raise Http404(_('Directory indexes are not allowed here.'))
    if manifest_asset_prefix and not fullpath.exists():
        possible_asset = get_manifest_asset(path)
        manifest_asset_prefix = (
            f'/{manifest_asset_prefix}' if not manifest_asset_prefix.startswith('/') else manifest_asset_prefix
        )
        if possible_asset.startswith(manifest_asset_prefix):
            possible_asset = possible_asset[len(manifest_asset_prefix) :]
        fullpath = Path(safe_join(document_root, possible_asset))
    if not fullpath.exists():
        raise Http404(_('“%(path)s” does not exist') % {'path': fullpath})
    # Respect the If-Modified-Since header.
    statobj = fullpath.stat()
    if not was_modified_since(request.META.get('HTTP_IF_MODIFIED_SINCE'), statobj.st_mtime):
        return HttpResponseNotModified()
    content_type, encoding = static_file_content_type_and_encoding(str(fullpath))

    response = RangedFileResponse(request, fullpath.open('rb'), content_type=content_type)
    response['Last-Modified'] = http_date(statobj.st_mtime)
    if encoding:
        response['Content-Encoding'] = encoding
    return response

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Run collectstatic (and rebuild the frontend app) so the requested asset exists in document_root.
  2. Rebuild/redeploy together: serve the frontend index.html from the same build that produced the hashed assets.
  3. Verify document_root/STATIC_ROOT points to the directory actually containing the files.
  4. If the manifest prefix feature is in use, ensure the webpack manifest file is present and the asset path falls under the configured prefix.

Example fix

// before
GET /static/react-app/main.OLDHASH.js -> 404

// after (rebuild + collectstatic, then serve matching index)
GET /static/react-app/main.123456.js -> 200
Defensive patterns

Strategy: fallback

Validate before calling

from pathlib import Path
def asset_exists(document_root, path):
    return Path(document_root, path.lstrip('/')).exists()

Try / catch

try:
    return serve(request, path, document_root)
except Http404:
    # fallback: serve index.html for SPA routes or return a clear 404
    return serve(request, 'index.html', document_root)

Prevention

When it happens

Trigger: GET of a static path where Path(safe_join(document_root, path)).exists() is False, and either manifest_asset_prefix is not configured or the manifest-resolved asset also does not exist.

Common situations: Frontend built without running collectstatic; React app build output missing or versioned filenames changed after redeploy (stale index.html referencing old hashed assets); wrong STATIC_ROOT/document_root in deployment.

Related errors


AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29). Data as JSON: /api/errors/14382fb39665f18d. Report an issue: GitHub.