2

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.

jchung
  • 903
  • 1
  • 11
  • 23

4 Answers4

3

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' %} 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.

Rafael
  • 525
  • 7
  • 20
2

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

Here is the docs on this.

Lord Elrond
  • 13,430
  • 7
  • 40
  • 80
  • Thanks. I did create the `staticfiles` directory manually, and I ran `heroku run python manage.py collectstatic`. It ran, with the output `0 static files copied to '/app/staticfiles', 377 unmodified, 153 post-processed.` I'm guessing that `angular.min.js` is one of the unmodified ones. – jchung Sep 13 '19 at 19:33
2

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.

jchung
  • 903
  • 1
  • 11
  • 23
  • Not sure what hte proper procedure is here... Should I delete the question? Should I leave it up? Would appreciate any guidance from the community here on the proper way to handle finding out that my bug wasn't in the question itself. – jchung Sep 14 '19 at 22:45
  • Leave it here. It's a valid problem, which also affects others. (See my answer for a root cause analysis.) – Peterino Jun 21 '23 at 10:11
0

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.

Peterino
  • 15,097
  • 3
  • 28
  • 29