Unable to upload media in CMS: "UNPUBLISHED ENTRY PERSIST FAILURE"

Hello, I am encountering a strange issue with me Netlify CMS + Gatsby site; I am unable to upload new images through the admin console.

Creating new posts and modifying existing posts using existing images (from the Kaldi coffee starter) works just fine. So does adding new images using the CMS when running locally in dev mode & pushing.

However, when using the CMS part of the deployed site I (and any other author) gets the message “Failed to persist entry: API_ERROR”. The image is shown in the preview but I am unable to save. The details from the console are:

type: UNPUBLISHED_ENTRY_PERSIST_FAILURE
payload:
	collection: "blog"
	slug: ""
	error: API_ERROR 
		at new t (https://<app_subdomain>.netlify.app/admin/netlify-cms-app.js:14:155265)
		at new i (https://<app_subdomain>.netlify.app/admin/netlify-cms-app.js:14:155631)
		at l.handleRequestError (https://<app_subdomain>.netlify.app/admin/netlify-cms-app.js:437:27943)
		at l.request (https://<app_subdomain>.netlify.app/admin/netlify-cms-app.js:14:227269)
		at async l.uploadBlob (https://<app_subdomain>.netlify.app/admin/netlify-cms-app.js:18:8781)
		at async Promise.all (index 0)
		at async l.persistFiles (https://<app_subdomain>.netlify.app/admin/netlify-cms-app.js:18:610)
		at async t.runWithLock (https://<app_subdomain>.netlify.app/admin/netlify-cms-app.js:109:126886)
		at async K.persistEntry (https://<app_subdomain>.netlify.app/admin/netlify-cms-app.js:8:39574)
		at async https://<app_subdomain>.netlify.app/admin/netlify-cms-app.js:8:322692
	

In the network tab I can see a failed request to https://<app_subdomain>.netlify.app/.netlify/git/github/git/blobs with the response code 408

Modifying any other field works just fine. Modifying this image field with an existing image works just fine. Creating a new post with an existing image works just fine.

I am using the ‘editorial_workflow’ but have confirmed the same behavior with the ‘simple’ workflow.

This is the relevant part of my config.yml, happy to post the rest if needed.

backend:
  name: git-gateway
  branch: main
  repo: <org>/<repo>
  commit_messages:
    create: 'Create {{collection}} “{{slug}}”'
    update: 'Update {{collection}} “{{slug}}”'
    delete: 'Delete {{collection}} “{{slug}}”'
    uploadMedia: '[skip ci] Upload “{{path}}”'
    deleteMedia: '[skip ci] Delete “{{path}}”'

# site_url: https://www.netlifycms.org
publish_mode: editorial_workflow
local_backend: true
media_folder: static/img
public_folder: /img

and this is my gatsby-config.js:

const { createProxyMiddleware } = require("http-proxy-middleware")

module.exports = {
  flags: {
    DEV_SSR: false,
    PARALLEL_SOURCING: false,
  },
  siteMetadata: {
    title: '',
    description: '',
  },
  plugins: [
    'gatsby-plugin-react-helmet',
    {
      // keep as first gatsby-source-filesystem plugin for gatsby image support
      resolve: 'gatsby-source-filesystem',
      options: {
        path: `${__dirname}/static/img`,
        name: 'uploads',
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        path: `${__dirname}/content`,
        name: 'pages',
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        path: `${__dirname}/src/img`,
        name: 'images',
      },
    },
    'gatsby-plugin-image',
    'gatsby-plugin-sharp',
    'gatsby-transformer-sharp',
    {
      resolve: 'gatsby-transformer-remark',
      options: {
        plugins: [
          {
            resolve: 'gatsby-remark-relative-images',
            options: {
              // staticFolderName: 'static',
              name: "uploads",
            },
          },
          {
            resolve: 'gatsby-remark-images',
            options: {
              // It's important to specify the maxWidth (in pixels) of
              // the content container as this plugin uses this as the
              // base for generating different widths of each image.
              maxWidth: 2048,
            },
          },
          {
            resolve: "gatsby-remark-copy-linked-files",
            options: {
              destinationDir: "static",
            },
          },
        ],
      },
    },
    {
      resolve: 'gatsby-plugin-flexsearch',
      options: {
        type: 'MarkdownRemark',
        fields: [
          {
            name: 'id',
            indexed: false,
            resolver: 'id',
            store: true,
          },
          {
            name: 'templateKey',
            indexed: false,
            resolver: 'frontmatter.templateKey',
            store: true,
          },
          {
            name: 'slug',
            indexed: false,
            resolver: 'fields.slug',
            store: true,
          },
          {
            name: 'locale',
            indexed: false,
            resolver: 'fields.locale',
            store: true,
          },
          {
            name: 'title',
            indexed: true,
            resolver: 'frontmatter.title',
            attributes: {
              encode: 'extra',
              tokenize: 'full',
              threshold: 1,
              resolution: 3,
            },
            store: true,
          },
          {
            name: 'overview',
            indexed: true,
            resolver: 'frontmatter.overview',
            attributes: {
              encode: 'icase',
              tokenize: 'forward',
              threshold: 2,
              depth: 3,
            },
            store: true,
          },
          {
            name: 'html',
            indexed: true,
            resolver: 'internal.content',
            attributes: {
              encode: 'balance',
              tokenize: 'strict',
              threshold: 0,
              resolution: 3,
              depth: 3,
            },
            store: true,
          },
        ],
      },
    },
    'gatsby-plugin-postcss',
    {
      resolve: "gatsby-plugin-purgecss", // purges all unused/unreferenced css rules
      options: {
        develop: true, // Activates purging in npm run develop
        tailwind: true,
        purgeOnly: ["/global.css"], // applies purging only on the tailwind file
      },
    }, // must be after other CSS plugins
    {
      resolve: 'gatsby-plugin-netlify-cms',
      options: {
        modulePath: `${__dirname}/src/cms/cms.js`,
      },
    },
  ],
  developMiddleware: app => {
    app.use(
      "/.netlify/functions/",
      createProxyMiddleware({
        target: "http://localhost:9000",
        pathRewrite: {
          "/.netlify/functions/": "",
        },
      })
    )
  },
}

These are the dependencies from package.json:

  "dependencies": {
    "@tailwindcss/forms": "^0.4.0",
    "autoprefixer": "^10.4.2",
    "gatsby": "^3.14.6",
    "gatsby-background-image": "^1.5.3",
    "gatsby-plugin-flexsearch": "^1.0.3",
    "gatsby-plugin-image": "^1.14.2",
    "gatsby-plugin-netlify-cms": "^5.14.0",
    "gatsby-plugin-postcss": "^4.14.0",
    "gatsby-plugin-purgecss": "^5.0.0",
    "gatsby-plugin-react-helmet": "^4.14.0",
    "gatsby-plugin-sharp": "^3.14.3",
    "gatsby-remark-copy-linked-files": "^4.11.0",
    "gatsby-remark-images": "^5.11.0",
    "gatsby-remark-relative-images": "^2.0.2",
    "gatsby-source-filesystem": "^3.14.0",
    "gatsby-transformer-remark": "^4.11.0",
    "gatsby-transformer-sharp": "^3.14.0",
    "lodash": "^4.17.15",
    "lodash-webpack-plugin": "^0.11.4",
    "luxon": "^2.3.0",
    "netlify-cms-app": "^2.15.67",
    "postcss": "^8.4.6",
    "prop-types": "^15.6.0",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-helmet": "^6.0.0",
    "tailwindcss": "^3.0.22",
    "uuid": "^7.0.0"
  },

After digging into this a little more & debugging some more, it seems like the issue could be with the “Git Gateway” backend, is this possible?

The repo is in a private Github repo.

Hi @matt_de_young. By private github repo, do you mean an organization account? If so, you need to grant access to your Netlify CMS instance:

Hi Tom,
Thanks for the response I do mean a private repo in an organization account. I have already granted access to the app. Again, all other authoring works just fine.

If this helps, I was able to recreate the issue in a public starter repo. I would be happy to create an identity account for you or anyone else who wants to look.

@erez would you happen to know if something obvious could’ve gone wrong in the process of granting an organization account access?

@matt_de_young have you tried disabling the Netlify identity instance and re-enabling it? And the same for git gateway in the identity settings? I’m assuming you’re not using large media, but let us know if you do.

@tomrutgers, I have tried disabling Netlify identity & git gateway then re-enabling them. I am now getting results that are inconsistent. It seems to work most of the time when just uploading new media and fails most of the time when doing so as part of editing a post, even with the same image. I know that’s not super helpful so I am going to keep trying to find a pattern.

The request to https://<app_subdomain>.netlify.app/.netlify/git/github/git/blobs is now failing with a 502

I am not using Netlify Large Media but plan to do so in the future for serving some PDFs.

Following up on this, Is there any limit to the size of images that can be uploaded in this way? I noticed that some of the images my authors are uploading are very large. One of them is 8.5 MB!

Github has a hard file size of 100MB, other than that I’m not aware of any restrictions, no. Is uploading 8.5MB images to git a good idea? Probably not. I’m don’t think it should be a problem for the CMS though, unless it’s authored on a poor network or something.

Lol, yes I think that is a separate issue I will have to address.

1 Like

Hi @tomrutgers and @matt_de_young :wave: I can’t think of anything specific, but big images could be related to Timeout uploading large files · Issue #4538 · netlify/netlify-cms · GitHub.

If you have a public repo with the issue, I suggest opening an issue on the CMS repo.

Also, you could try using the GitHub backend directly to see if related to git-gateway.

2 Likes

I wanted to follow up here. I am still unable to find some underlying cause. My starter template I created to test the issue seems to now be working 100% of the time (even with 28 MB images!). The original repo seems to be working reliably at least with reasonably sized images.

I thought I was carefully controlling for all possible issues but I guess not. This is no longer blocking my work on the original repo so I think it is resolved for now. If I am ever able to find a real pattern to why it seems to work sometimes but not others I will create an issue in the Netlify-CMS repo or revive this thread.

Thanks for your help.

1 Like

Thanks for following up Matt!

1 Like