chenhg5/cc-connect · error
resolve parent channel %s: %w
Error message
resolve parent channel %s: %w
What it means
When the cron target channel is itself a thread, resolveCronReplyTarget must resolve the parent channel (ch.ParentID) to know what kind of standalone thread to create. Failure to resolve the parent is wrapped as "resolve parent channel <id>: <cause>". An empty ParentID returns core.ErrNotSupported separately.
Source
Thrown at platform/discord/discord.go:442
func resolveCronReplyTarget(sessionKey, title string, ops discordThreadOps) (string, replyContext, error) {
channelID, err := parseDiscordSessionKeyChannelID(sessionKey)
if err != nil {
return "", replyContext{}, err
}
ch, err := ops.ResolveChannel(channelID)
if err != nil {
return "", replyContext{}, fmt.Errorf("resolve channel %s: %w", channelID, err)
}
parentChannelID := channelID
parentType := ch.Type
if isThreadChannelType(ch.Type) {
if ch.ParentID == "" {
return "", replyContext{}, core.ErrNotSupported
}
parent, err := ops.ResolveChannel(ch.ParentID)
if err != nil {
return "", replyContext{}, fmt.Errorf("resolve parent channel %s: %w", ch.ParentID, err)
}
parentChannelID = ch.ParentID
parentType = parent.Type
}
threadType, ok := standaloneThreadType(parentType)
if !ok {
return "", replyContext{}, core.ErrNotSupported
}
thread, err := ops.StartStandaloneThread(parentChannelID, freshThreadName(title), threadType, 1440)
if err != nil {
return "", replyContext{}, fmt.Errorf("start thread in channel %s: %w", parentChannelID, err)
}
if err := ops.JoinThread(thread.ID); err != nil {
slog.Debug("discord: join fresh thread failed", "thread", thread.ID, "error", err)
}
View on GitHub (pinned to 4000b2338a)
Solutions
- Inspect the wrapped cause: not-found usually means the parent channel was deleted.
- Re-point the cron job at a normal text channel instead of a thread of a deleted channel.
- Grant the bot ViewChannel on the parent channel/category, not just the thread.
- Retry on transient API errors with backoff.
Example fix
// before
parent, err := ops.ResolveChannel(ch.ParentID)
if err != nil {
return "", replyContext{}, fmt.Errorf("resolve parent channel %s: %w", ch.ParentID, err)
}
// after
parent, err := ops.ResolveChannel(ch.ParentID)
if err != nil {
slog.Warn("discord: cannot resolve thread parent for cron, using thread channel directly", "parent", ch.ParentID, "error", err)
parentChannelID = channelID
parentType = ch.Type
} Defensive patterns
Strategy: fallback
Validate before calling
if ch.ParentID == "" {
return core.ErrNotSupported // check before resolving parent
}
if _, err := ops.ResolveChannel(ch.ParentID); err != nil {
slog.Warn("discord: thread parent unresolvable for cron", "parent", ch.ParentID)
} Try / catch
parent, err := ops.ResolveChannel(ch.ParentID)
if err != nil {
// degrade: create the standalone thread in the thread's own channel scope or skip
return "", replyContext{}, fmt.Errorf("resolve parent channel %s: %w", ch.ParentID, err)
} Prevention
- Grant the bot visibility on parent channels/categories, not just threads.
- Clean up cron jobs whose target threads' parents have been deleted.
- Prefer scheduling crons on plain text channels to avoid parent resolution entirely.
When it happens
Trigger: ops.ResolveChannel(ch.ParentID) fails for the thread's parent — parent channel deleted, bot lacks access to the parent (but can see the thread), or a transient Discord API error.
Common situations: Threads whose parent channel was deleted (orphaned threads), permission asymmetry where the bot sees a thread but not its parent category/channel, Discord API hiccups during cron firing.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- start thread in channel %s: %w
- cron job not found
- cron project not found
- codex app-server start returned empty thread id
- %s must be true or false
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/9548e3cac7f60211.
Report an issue: GitHub.