BigPizzaV3/CodexPlusPlus · error
API 地址须使用 HTTPS,且不含账号、密码、查询参数或片段
Error message
API 地址须使用 HTTPS,且不含账号、密码、查询参数或片段
What it means
apiEndpoint() accepts only https: URLs and additionally rejects URLs that embed credentials (username/password), query strings (?...), or fragments (#...). This prevents leaking secrets via the URL and guarantees a deterministic endpoint path. It throws this error for any http:// URL or URL containing those components.
Solutions
- Use https:// instead of http:// (put the service behind TLS or use a TLS-terminating reverse proxy)
- Move the API key out of the URL into the key/password field — the code appends the key as a bearer credential, not a query param
- Remove ?query=... and #fragment parts from the URL
- Remove user:password@ from the URL
Example fix
// before
apiEndpoint('http://localhost:8080/v1?key=abc')
// after
apiEndpoint('https://my-tls-proxy.example.com/v1') // key goes in the API Key field Defensive patterns
Strategy: validation
Validate before calling
function checkUrl(raw) {
try {
const u = new URL(String(raw).trim());
if (u.protocol !== 'https:') return 'must be https://';
if (u.username || u.password) return 'remove credentials from URL';
if (u.search || u.hash) return 'remove ?query and #fragment';
return null;
} catch { return 'not a valid absolute URL'; }
} Type guard
function isCleanHttpsUrl(u) { return u instanceof URL && u.protocol === 'https:' && !u.username && !u.password && !u.search && !u.hash; } Try / catch
let endpoint;
try { endpoint = apiEndpoint(raw); } catch (e) { if (String(e).includes('HTTPS')) { showTlsGuidance(); } return; } Prevention
- Never embed API keys as ?key= query params — use the key field
- Use TLS-terminating reverse proxies for local services instead of plain http
- Strip #anchors copied from browser address bars
- Keep the API key out of URLs entirely for security
When it happens
Trigger: apiEndpoint('http://api.example.com/v1'); a URL like https://user:pass@host/v1; URLs with ?api-key=... or #section; any of these after successful URL parsing.
Common situations: User configures a local HTTP-only proxy (http://localhost:11434/v1); user pastes a URL that already includes an API key as a query parameter; user includes credentials in the URL instead of the API Key field.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- API 地址须使用 HTTPS,且不含账号、密码、查询参数或片段
- Base URL 必须使用 HTTPS
- 链接缺少解密密钥。请使用完整的分享链接。
- Base URL 不能为空
- 上游 Base URL 不能为空
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/d7d2131be1bd703a.
Report an issue: GitHub.
Appendix: source
Thrown at tools/conversation-canvas/external-api.mjs:4
// OpenAI-compatible Chat Completions. Never persist credentials in tree checkpoints.
export function apiEndpoint(raw){
let url;try{url=new URL(String(raw).trim());}catch{throw Error('请输入完整的 HTTPS API 地址');}
if(url.protocol!=='https:'||url.username||url.password||url.search||url.hash)throw Error('API 地址须使用 HTTPS,且不含账号、密码、查询参数或片段');
const path=url.pathname.replace(/\/+$/,'');
url.pathname=path.endsWith('/chat/completions')?path:(path||'/v1')+'/chat/completions';
return url.href;
}
export function apiConfig(input){
const channel=input?.channel==='external'?'external':'native';
const value={channel,baseUrl:String(input?.baseUrl||'').trim(),model:String(input?.model||'').trim(),key:String(input?.key||'').trim(),remember:input?.remember===true,speed:input?.speed==='provider'?'provider':'fast',revision:input?.revision||crypto.randomUUID()};
if(channel==='external'){
value.endpoint=apiEndpoint(value.baseUrl);
if(!value.model||value.model.length>200)throw Error('请填写 API 的模型名称');
if(!value.key||/[\r\n]/.test(value.key))throw Error('请在设置中填写有效 API Key');
}
return value;
}
export function storedApiConfig(config){
const {channel,baseUrl,model,remember,speed,revision}=config;View on GitHub (pinned to b1ed92e5e4)