mihomo-party-org/clash-party · error
Subscription failed: Profile is not a valid YAML
Error message
Subscription failed: Profile is not a valid YAML
What it means
fetchAndValidateSubscription fetches a remote profile, decrypts it with the Age key, and parses the plaintext as YAML. If `parse` returns null or a non-object (string, number, boolean), the function logs the failure and throws 'Subscription failed: Profile is not a valid YAML'. This means the decrypted payload was not a YAML mapping, so the content cannot become a mihomo profile.
Source
Thrown at src/main/config/profile.ts:409
`Remote profile response url=${redactedUrl} mode=${fetchMode} status=${res.status} contentType=${String(
responseHeaders['content-type'] || ''
)} bytes=${Buffer.byteLength(data, 'utf8')}`
)
if (res.status < 200 || res.status >= 300) {
await profileLogger.warn(
`Remote profile request rejected url=${redactedUrl} mode=${fetchMode} status=${res.status}`
)
throw new Error(`Subscription failed: Request status code ${res.status}`)
}
const decryptedData = await decryptAgeContent(data, options.ageSecretKey, 'subscription')
const parsed = parse(decryptedData) as Record<string, unknown> | null
if (typeof parsed !== 'object' || parsed === null) {
await profileLogger.warn(
`Remote profile parse failed url=${redactedUrl} mode=${fetchMode} parsedType=${typeof parsed}`
)
throw new Error('Subscription failed: Profile is not a valid YAML')
}
await profileLogger.info(
`Remote profile parsed url=${redactedUrl} mode=${fetchMode} summary=${parsedProfileSummary(parsed)}`
)
if (!parsed['proxies'] && !parsed['proxy-providers']) {
await profileLogger.warn(
`Remote profile validation failed url=${redactedUrl} mode=${fetchMode} reason=missing-proxies-or-providers summary=${parsedProfileSummary(
parsed
)}`
)
throw new Error('Subscription failed: Profile missing proxies or providers')
}
return { data, headers: responseHeaders }
}
export async function createProfile(item: Partial<IProfileItem>): Promise<IProfileItem> {
const id = item.id || new Date().getTime().toString(16)View on GitHub (pinned to 911e090537)
Solutions
- Open the subscription URL in a browser/curl and confirm it returns a YAML mapping with top-level keys.
- Verify the ageSecretKey matches the key the subscription was encrypted with.
- Re-import the subscription with a correct URL; check for provider login/captcha pages.
- Inspect the warn log line 'Remote profile parse failed url=...' to see parsedType and the fetch mode used.
Example fix
// before
await fetchSub(url, { ageSecretKey: 'old-key' })
// after
// verify the payload first
curl -H 'User-Agent: clash-verge' <url> | head
await fetchSub(url, { ageSecretKey: 'correct-key' }) Defensive patterns
Strategy: validation
Validate before calling
const res = await fetch(url)
const text = await res.text()
if (!text.trim()) throw new Error('subscription body is empty')
const parsed = YAML.parse(text)
if (typeof parsed !== 'object' || parsed === null) {
throw new Error('subscription did not return a YAML object')
} Type guard
function isYamlObject(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v)
} Try / catch
try {
await fetchSub(url, { ageSecretKey })
} catch (e) {
if (e.message.includes('Profile is not a valid YAML')) {
// verify URL/key, surface a re-import prompt
}
} Prevention
- Verify subscription URLs return YAML mappings before saving them.
- Keep the ageSecretKey in sync with the provider's encryption key.
- Watch for provider auth/captcha responses during automated imports.
When it happens
Trigger: Calling fetchSub/fetchAndValidateSubscription when the remote subscription (after Age decryption with the supplied ageSecretKey) yields YAML that parses to null or a scalar — e.g. an empty body, a plain string, or `null` document.
Common situations: Subscription URL returns empty body or plain text (auth/captcha page stored as text); wrong or stale ageSecretKey causing decryption to produce garbage that parses to a non-object; provider returning a bare value like a token string instead of YAML config.
Related errors
- Subscription failed: Profile missing proxies or providers
- Profile "${id}" contains HTML instead of YAML. The subscript
- Empty URL
- Failed to parse profile "${id}": ${msg}
- Invalid latest.yml from update source
AI-assisted analysis of mihomo-party-org/clash-party@911e090537 (2026-08-30).
Data as JSON: /api/errors/5c1278ffc96458a5.
Report an issue: GitHub.