jchung
jchung

Reputation: 953

Django ValueError: Missing staticfiles manifest entry, but the manifest appears to show the entry

On a Django 1.11 app deployed to Heroku. When loading the root URL / (and I presume when Django gets to {% static 'angular/angular.min.js' %} in the homepage.html template) I get the following error:

ValueError: Missing staticfiles manifest entry for 'angular/angular.min.js'
  File "django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "homepage/views.py", line 87, in homepage
    "latest_python3": Version.objects.filter(supports_python3=True).select_related("package").distinct().order_by("-created")[0:5]
  File "django/shortcuts.py", line 30, in render
    content = loader.render_to_string(template_name, context, request, using=using)
  File "django/template/loader.py", line 68, in render_to_string
    return template.render(context, request)
  File "django/template/backends/django.py", line 66, in render
    return self.template.render(context)
  File "django/template/base.py", line 207, in render
    return self._render(context)
  File "newrelic/api/function_trace.py", line 60, in dynamic_wrapper
    return wrapped(*args, **kwargs)
  File "django/template/base.py", line 199, in _render
    return self.nodelist.render(context)
  File "django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "django/template/loader_tags.py", line 177, in render
    return compiled_parent._render(context)
  File "newrelic/api/function_trace.py", line 60, in dynamic_wrapper
    return wrapped(*args, **kwargs)
  File "django/template/base.py", line 199, in _render
    return self.nodelist.render(context)
  File "django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "django/template/defaulttags.py", line 411, in render
    return strip_spaces_between_tags(self.nodelist.render(context).strip())
  File "django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "newrelic/hooks/framework_django.py", line 765, in wrapper
    return wrapped(*args, **kwargs)
  File "django/template/loader_tags.py", line 72, in render
    result = block.nodelist.render(context)
  File "django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "django/templatetags/static.py", line 105, in render
    url = self.url(context)
  File "django/templatetags/static.py", line 102, in url
    return self.handle_simple(path)
  File "django/templatetags/static.py", line 117, in handle_simple
    return staticfiles_storage.url(path)
  File "django/contrib/staticfiles/storage.py", line 162, in url
    return self._url(self.stored_name, name, force)
  File "django/contrib/staticfiles/storage.py", line 141, in _url
    hashed_name = hashed_name_func(*args)
  File "django/contrib/staticfiles/storage.py", line 432, in stored_name
    raise ValueError("Missing staticfiles manifest entry for '%s'" % clean_name)

What's in the manifest?

My understanding of the Django docs is that the manifest is a file called staticfiles.json. That file appears to contain the correct entry (For formatting reasons I have removed all unrelated entries):

$ heroku run cat ./staticfiles/staticfiles.json
Running cat ./staticfiles/staticfiles.json
{"paths": {"angular/angular.min.js": "angular/angular.min.df1c56732ca5.js", "angular/controllers.js": "angular/controllers.af8e9f9a2645.js"}, "version": "1.0"}

Relevant Settings:

I followed Heroku's instructions for service Static Files with Django:

# in requirements.txt
whitenoise

# in settings/base.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
STATIC_URL = "/static/"
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static"),]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    # ...others here too
]

django_heroku.settings(locals())

(UPDATE: STATICFILES_STORAGE)

Based on one of the suggestions below, I removed the value of STATICFILES_STORAGE. django-heroku sets the value of STATICFILES_STORAGE to whitenoise.storage.CompressedManifestStaticFilesStorage. I removed this by adding del STATICFILES_STORAGE to the end of my settings.py file. Django then reset the value to the default django.contrib.staticfiles.storage.StaticFilesStorage. The result is that all of the static files either 404 or get MIME type errors in the browser.

Upvotes: 4

Views: 3907

Answers (4)

Rafael
Rafael

Reputation: 574

Hint for anyone who landed here via a search

I had the same issue and in my case, I had to remove a slash at the beginning.

Changing:

{% static '/admin/js/vendor/jquery/jquery.js' %}

to:

{% static 'admin/js/vendor/jquery/jquery.js' %}

(Removed the first forward slash)

Fixed the problem in my case.


I'm aware that this isn't directly related to this exact problem, but because I landed here with my problem I thought I'd post it here and hope this will help someone landing here in the future.

Upvotes: 6

Peterino
Peterino

Reputation: 16777

The ValueError is raised by the Django staticfiles app, but – in your case – it actually comes from WhiteNoise, from whitenoise.storage.CompressedManifestStaticFilesStorage to be precise. The topic is discussed in the "Additional Notes" section of the WhiteNoise docs on Django.

Just for reference, I get the same error, for example, when I run tests using Pytest over Django Restframework endpoints (with a format=api request context).

The WhiteNoise docs suggest to analyze the problem using findstatic, and if nothing else helps to silence the error via WHITENOISE_MANIFEST_STRICT = False in your Django project settings.

This likely boils down to running collectstatic before anything (even before running tests), e.g.

python manage.py collectstatic --noinput

P.S.: You should not add del STATICFILES_STORAGE to the end of your settings module. This will defeat the purpose of using WhiteNoise for static file optimization.

Upvotes: 1

jchung
jchung

Reputation: 953

Update: This problem is now fixed. The solution sadly won't be useful to others. Apologies for that. The problem was that my settings were being overwritten by settings in another module that was being imported. The settings I listed in the question above actually do work on Heroku. Sorry everyone, and thanks to those who helped me debug this.

Upvotes: 2

Lord Elrond
Lord Elrond

Reputation: 16062

Did you manually create the staticfiles directory, then run django-admin collectstatic before deployment?

Here is the docs on this.

Upvotes: 2

Related Questions