can1357/oh-my-pi · error · Error
seafile share response did not include a Location URL
Error message
seafile share response did not include a Location URL
What it means
The Seafile uploader expects the share-link creation response to yield a public URL, either from the Location header of a redirect (fetch is called with redirect: "manual") or from the JSON body's shareLink field. If neither is present, the response cannot be turned into a share URL and the upload fails fast with this error. It guards against silent misconfiguration of the Seafile server or an unexpected API response shape.
Source
Thrown at packages/coding-agent/src/blob-broker/uploaders-self-hosted.ts:433
const shareForm = new URLSearchParams({
p: `${directory === "/" ? "" : directory}/${filename}`,
share_type: "download",
});
if (sharePassword) shareForm.set("password", sharePassword);
if (expiryDays !== undefined && expiryDays > 0) shareForm.set("expire", String(expiryDays));
const shareResponse = await expectOk(
await requestFetch(`${endpoint(apiUrl, "repos", repositoryId, "file", "shared-link")}/`, {
method: "PUT",
headers: { ...headers, "Content-Type": "application/x-www-form-urlencoded" },
body: shareForm,
redirect: "manual",
}),
"seafile",
);
let location = shareResponse.headers.get("Location") ?? undefined;
if (!location) location = shareLink(parseJsonText(await shareResponse.text()));
if (!location) throw new Error("seafile share response did not include a Location URL");
const resultUrl = new URL(location, apiUrl);
if (raw) resultUrl.searchParams.set("raw", "1");
return publication("seafile", request, resultUrl.toString(), {
...(expiryInfo.expiresAt === undefined ? {} : { expiresAt: expiryInfo.expiresAt }),
});
},
};
}
function plikFile(value: unknown): PlikFile | undefined {
let candidate: unknown = value;
if (Array.isArray(candidate)) candidate = candidate[0];
if (typeof candidate === "object" && candidate !== null && "file" in candidate) candidate = candidate.file;
if (typeof candidate !== "object" || candidate === null || !("id" in candidate)) return undefined;
const id = identifier(candidate.id);
if (!id) return undefined;
const name =
"fileName" in candidateView on GitHub (pinned to 9690622007)
Solutions
- Verify the Seafile API base URL and token: curl the share-link endpoint manually and inspect the response body/headers
- Check the Seafile server version and confirm it returns shareLink (or sets Location) on POST /api/v2.1/share-links/
- Check for a reverse proxy rewriting/stripping the Location header
- Inspect the raw response body in logs to see the server's error message (e.g. permission denied on the library)
Example fix
// before: server returns error JSON with no shareLink
if (!location) throw new Error("seafile share response did not include a Location URL");
// after: log the body to diagnose
if (!location) throw new Error(`seafile share response did not include a Location URL: ${await shareResponse.text()}`); Defensive patterns
Strategy: try-catch
Validate before calling
const res = await fetch(shareUrl, { method: "POST", headers, redirect: "manual" });
const loc = res.headers.get("Location") ?? (await res.json())?.shareLink;
if (!loc) throw new Error(`Seafile returned no share link: HTTP ${res.status}`); Type guard
function hasShareLink(v: unknown): v is { shareLink: string } {
return typeof v === "object" && v !== null && typeof (v as { shareLink?: unknown }).shareLink === "string";
} Try / catch
try {
await uploader.upload(req);
} catch (err) {
if (err instanceof Error && err.message.includes("seafile share response")) {
// log Seafile base URL/token, inspect server response, surface actionable message
}
throw err;
} Prevention
- Verify Seafile API token and base URL with curl before wiring into config
- Test POST /api/v2.1/share-links/ manually and confirm shareLink/Location is present
- Watch for reverse proxies stripping Location headers
- Pin/verify Seafile server version compatibility
When it happens
Trigger: The POST to the Seafile share-link endpoint (api/v2.1/share-links/) returns 2xx but includes no Location header and its JSON body lacks a usable shareLink value — e.g. the server responds with an empty body, an error object with no link field, or a non-redirect response because the endpoint path or auth token is wrong.
Common situations: Misconfigured SEAFILE server URL or API token causing the server to answer with a JSON error instead of a share link; a Seafile version whose share-link response format differs (older API versions return different field names); a reverse proxy stripping Location headers on manual-redirect responses.
Related errors
- plik file response did not include an id
- ${destination} returned an invalid response
- ${destination} returned invalid JSON
- owncloud share response did not include an OCS envelope
- plik upload metadata did not include an id and upload token
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/8dd88b691fed1a2a.
Report an issue: GitHub.