gethomepage/homepage · error · Error

Error getting data from Audiobookshelf: ${status}. Data: ${d

Error message

Error getting data from Audiobookshelf: ${status}. Data: ${data.toString()}

What it means

Thrown by retrieveFromAPI in the Audiobookshelf proxy when the upstream Audiobookshelf HTTP API returns any non-200 status. The proxy forwards credentials as a Bearer token and expects a 200 with JSON; any other status (auth failure, network error reflected as a 4xx/5xx, or a redirect) is treated as fatal before JSON parsing.

Source

Thrown at src/widgets/audiobookshelf/proxy.js:19

import getServiceWidget from "utils/config/service-helpers";
import createLogger from "utils/logger";
import { formatApiCall } from "utils/proxy/api-helpers";
import { httpProxy } from "utils/proxy/http";
import widgets from "widgets/widgets";

const proxyName = "audiobookshelfProxyHandler";
const logger = createLogger(proxyName);

async function retrieveFromAPI(url, key) {
  const headers = {
    "content-type": "application/json",
    Authorization: `Bearer ${key}`,
  };

  const [status, , data] = await httpProxy(url, { headers });

  if (status !== 200) {
    throw new Error(`Error getting data from Audiobookshelf: ${status}. Data: ${data.toString()}`);
  }

  return JSON.parse(Buffer.from(data).toString());
}

export default async function audiobookshelfProxyHandler(req, res) {
  const { group, service, endpoint, index } = req.query;

  if (!group || !service) {
    logger.debug("Invalid or missing service '%s' or group '%s'", service, group);
    return res.status(400).json({ error: "Invalid proxy service type" });
  }

  const widget = await getServiceWidget(group, service, index);

  if (!widget) {
    logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group);
    return res.status(400).json({ error: "Invalid proxy service type" });

View on GitHub (pinned to b6dca1ae03)

Solutions

  1. Verify the Audiobookshelf service URL and that the host is reachable from the Homepage container (curl the same URL with the same token).
  2. Confirm the API key is valid in Audiobookshelf under Settings > Users and has not expired.
  3. Check the reverse proxy in front of Audiobookshelf returns 200 for the same path the widget calls.
  4. Inspect the Homepage debug log; data.toString() in the message often contains the upstream body (HTML error page, JSON error) that pinpoints 401/404/502.
  5. Ensure the URL template in the widget config resolves to the v1 API path Audiobookshelf expects.

Example fix

// before
if (status !== 200) {
  throw new Error(`Error getting data from Audiobookshelf: ${status}. Data: ${data.toString()}`);
}
// after
if (status !== 200) {
  throw new Error(`Audiobookshelf ${url} returned HTTP ${status}: ${Buffer.from(data).toString().slice(0, 200)}`);
}
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight the Audiobookshelf URL and key before the widget polls.
async function checkAudiobookshelf(base, key) {
  const res = await fetch(`${base.replace(/\/$/, "")}/api/items?n=1`, {
    headers: { Authorization: `Bearer ${key}` },
  });
  if (!res.ok) throw new Error(`Audiobookshelf pre-flight HTTP ${res.status}`);
  return true;
}

Type guard

function isAudiobookshelfErrorPayload(v) {
  return typeof v === "object" && v !== null && typeof v.error === "string";
}

Try / catch

try {
  const data = await retrieveFromAPI(url, key);
  res.json(data);
} catch (err) {
  logger.warn("Audiobookshelf proxy failed for %s: %s", url, err.message);
  res.status(502).json({ error: "Audiobookshelf unavailable", detail: err.message });
}

Prevention

When it happens

Trigger: Calling the Audiobookshelf /api/... endpoint with an invalid or expired API key (401/403), pointing the widget at the wrong URL so the path 404s, Audiobookshelf behind a reverse proxy returning 502/503, or a typo'd base URL hitting an unrelated server that does not return 200.

Common situations: API key mis-typed or copied with whitespace; base URL configured with a trailing slash or wrong port; Audiobookshelf upgraded and changed an endpoint path; reverse proxy (Traefik/Caddy/Nginx) returning an error page instead of proxying; token lacks permission for the requested endpoint.

Related errors


AI-assisted analysis of gethomepage/homepage@b6dca1ae03 (2026-08-13). Data as JSON: /api/errors/acf8bebe88d212c0. Report an issue: GitHub.