{"record":{"id":"1320a7926507aa3f","repo":"discordjs/discord.js","slug":"guildchannelorphan","errorCode":"GuildChannelOrphan","errorMessage":"GuildChannelOrphan","messagePattern":"GuildChannelOrphan","errorType":"error_code","errorClass":"DiscordjsError","httpStatus":null,"severity":"error","filePath":"packages/discord.js/src/structures/GuildChannel.js","lineNumber":286,"sourceCode":"    const basePermissions = new PermissionsBitField([role.permissions, role.guild.roles.everyone.permissions]);\n    const everyoneOverwrites = this.permissionOverwrites.cache.get(this.guild.id);\n    const roleOverwrites = this.permissionOverwrites.cache.get(role.id);\n\n    return basePermissions\n      .remove(everyoneOverwrites?.deny ?? PermissionsBitField.DefaultBit)\n      .add(everyoneOverwrites?.allow ?? PermissionsBitField.DefaultBit)\n      .remove(roleOverwrites?.deny ?? PermissionsBitField.DefaultBit)\n      .add(roleOverwrites?.allow ?? PermissionsBitField.DefaultBit)\n      .freeze();\n  }\n\n  /**\n   * Locks in the permission overwrites from the parent channel.\n   *\n   * @returns {Promise<GuildChannel>}\n   */\n  async lockPermissions() {\n    if (!this.parent) throw new DiscordjsError(ErrorCodes.GuildChannelOrphan);\n    const permissionOverwrites = this.parent.permissionOverwrites.cache.map(overwrite => overwrite.toJSON());\n    return this.edit({ permissionOverwrites });\n  }\n\n  /**\n   * A collection of cached members of this channel, mapped by their ids.\n   * Members that can view this channel, if the channel is text-based.\n   * Members in the channel, if the channel is voice-based.\n   *\n   * @type {Collection<Snowflake, GuildMember>}\n   * @readonly\n   */\n  get members() {\n    return this.guild.members.cache.filter(member =>\n      this.permissionsFor(member).has(PermissionFlagsBits.ViewChannel, false),\n    );\n  }\n","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/discordjs/discord.js/blob/a81ed8a306d37fdc746e26a634b6a42164ba2c8c/packages/discord.js/src/structures/GuildChannel.js#L268-L304","documentation":"GuildChannelOrphan is thrown by GuildChannel#lockPermissions when the channel has no parent — there is no parent channel from which to copy permission overwrites. 'Orphan' means the channel is not attached to a category (or the parent is uncached/unresolvable), so locking permissions from a parent is impossible.","triggerScenarios":"Calling channel.lockPermissions() on a channel whose parent is null — a top-level channel not inside any category, or a channel whose parent exists on Discord's side but isn't cached/resolved by the client yet.","commonSituations":"Syncing permissions of a channel programmatically when the channel was moved out of its category; running lockPermissions in setup scripts before the parent channel is fetched/cached; assuming every channel has a parent; comparing with the Discord UI 'Sync Permissions' which is disabled for non-category children.","solutions":["Check channel.parent before calling: `if (!channel.parent) return;` and skip or create a category first","Assign the channel to a category (channel.setParent(categoryId, { lockPermissions: true })) instead of manually locking","If the parent may be uncached, fetch it: `const parent = await channel.guild.channels.fetch(channel.parentId)` and copy its permissionOverwrites manually via channel.edit({ permissionOverwrites: ... })","Guard in bulk-sync loops: only call lockPermissions for channels where parentId is set"],"exampleFix":"// before\nawait channel.lockPermissions(); // throws when channel has no category\n// after\nif (!channel.parent) return;\nawait channel.lockPermissions();","handlingStrategy":"validation","validationCode":"if (!channel.parent) return; // orphan: nothing to lock from\nawait channel.lockPermissions();","typeGuard":"function hasParentChannel(channel) {\n  return channel.parent != null || typeof channel.parentId === 'string';\n}","tryCatchPattern":"try {\n  await channel.lockPermissions();\n} catch (err) {\n  if (err.name === 'DiscordjsError' && err.message.includes('GuildChannelOrphan')) {\n    return; // channel is not in a category; skip\n  }\n  throw err;\n}","preventionTips":["Skip lockPermissions for channels without parentId","Prefer channel.setParent(id, { lockPermissions: true }) when moving channels","Fetch/cache the parent channel before permission sync routines","Account for DM/group channels lacking guild parents in shared code paths"],"tags":["discord-js","channels","permissions","missing-parent"],"backgroundTag":"orphan-channel-no-parent","analyzedSha":"a81ed8a306d37fdc746e26a634b6a42164ba2c8c","analyzedAt":"2026-08-30T04:07:22.193Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}