Error thrown in createAuthHandler "Cannot set headers"

Hello, I’m following the nextjs github backend guide and I’m stuck on the Configure Custom App step. My configuration is basically the same as in the example, except my repo is private, so I’m using the authScope: 'repo' flag.

I looked at the code for createAuthHandler and I see res.setHeader is being called, and I assume that’s where the error is being thrown, but I’m not sure why Next.js has already sent the headers to the client. Any thoughts on why I’m getting this error?

Detailed error below, happy to include more info or share config if needed.

(node:9792) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:485:11)
    at /Users/project-path/node_modules/next-tinacms-github/dist/next-tinacms-github.cjs.development.js:139:13
    at processTicksAndRejections (internal/process/task_queues.js:93:5)

@pmb can you share the code calling next-tinacms-github or share a public reproduction?

Sure, these are the api files using next-tinacms-github, one thing to note: I am using App.getInitialProps in my Next.js custom app. Not sure if this would have an effect on it, but thought I’d point that out.

//proxy-github.js
import { apiProxy } from 'next-tinacms-github';

export default apiProxy(process.env.SIGNING_KEY);
//create-github-access-token.js
import { createAuthHandler } from 'next-tinacms-github';

export default createAuthHandler(
  process.env.GITHUB_CLIENT_ID,
  process.env.GITHUB_CLIENT_SECRET,
  process.env.SIGNING_KEY
);
//preview.js
import { previewHandler } from 'next-tinacms-github';

export default previewHandler(process.env.SIGNING_KEY);
//_app.js
const MyApp = ({ Component, pageProps, content }) => {
  //TinaCMS Github login
  const onLogin = async () => {
    const token = localStorage.getItem('tinacms-github-token') || null;
    const headers = new Headers();

    if (token) {
      headers.append('Authorization', 'Bearer ' + token);
    }

    const resp = await fetch('/api/preview', { headers: headers });
    const data = await resp.json();

    if (resp.status == 200) window.location.href = window.location.pathname;
    else throw new Error(data.message);
  };

  const onLogout = () => {
    return fetch('/api/reset-preview').then(() => {
      window.location.reload();
    });
  };

  const tinaConfig = {
    enabled: !!pageProps.preview,
    apis: {
      github: new GithubClient({
        proxy: '/api/proxy-github',
        authCallbackRoute: '/api/create-github-access-token',
        clientId: process.env.GITHUB_CLIENT_ID,
        baseRepoFullName: process.env.REPO_FULL_NAME,
        authScope: 'repo', // for private repos, normally defaults to 'public_repo'
        baseBranch: process.env.BASE_BRANCH,
      }),
    },
    sidebar: pageProps.preview,
    toolbar: pageProps.preview,
  };

  const cms = React.useMemo(() => new TinaCMS(tinaConfig), [tinaConfig]);

  return (
    <ThemeProvider theme={theme} components={components}>
      <TinaProvider cms={cms}>
        <TinacmsGithubProvider
          onLogin={onLogin}
          onLogout={onLogout}
          error={pageProps.error}
        >
          <ResourceProvider resources={content}>
            <EditLink cms={cms} />
            <Component {...pageProps} />
          </ResourceProvider>
        </TinacmsGithubProvider>
      </TinaProvider>
    </ThemeProvider>
  );
};

MyApp.getInitialProps = async appContext => {
  // calls page's `getInitialProps` and fills `appProps.pageProps`
  const appProps = await App.getInitialProps(appContext);

  const content = fetchAllContent();

  return { ...appProps, content };
};

export default MyApp;