yikart/AiToEarn · warning · AppException

ChannelPlatformOperationNotSupported

ChannelPlatformOperationNotSupported

Error message

ChannelPlatformOperationNotSupported

What it means

Threads publish-options only implements value lookup for the 'location_id' field; any other field key passed to getValues is rejected with ChannelPlatformOperationNotSupported naming Threads and the offending field. It is an unsupported-operation guard, not a data error.

Source

Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/threads/threads-publish-options.provider.ts:38

@Injectable()
export class ThreadsPublishOptionsProvider implements PublishOptionSourceProvider {
  constructor(private readonly threadsService: ThreadsService) {}

  listSources() {
    return [{
      field: 'location_id',
      label: 'Location',
      description: 'Threads post location',
      valueType: PublishOptionValueType.List,
      requiresAccount: true,
      filterSchema: ThreadsLocationFilterSchema,
    }]
  }

  async getValues(input: PublishOptionValuesInput): Promise<PublishOptionValuesResult> {
    if (input.field !== 'location_id') {
      throw new AppException(ResponseCode.ChannelPlatformOperationNotSupported, {
        platform: AccountType.Threads,
        field: input.field,
      })
    }

    const filters = ThreadsLocationFilterSchema.parse(input.filters ?? {})
    const locations = await this.threadsService.searchLocations(
      input.credential.accessToken,
      filters,
    )

    return {
      field: 'location_id',
      valueType: PublishOptionValueType.List,
      items: locations
        .filter(location => Boolean(location.id))
        .map(location => ({
          value: location.id,

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Only request option values for field='location_id' on the Threads platform.
  2. Filter the platform's supported fields (see the getSchema/filterSchema definitions above getValues) before calling getValues.
  3. If a new field is genuinely needed, extend getValues with a branch implementing that field's lookup rather than reusing location_id's path.
  4. Update the caller to handle ChannelPlatformOperationNotSupported as 'field unsupported' and skip the field gracefully.

Example fix

// before
for (const field of ['location_id', 'topic_id']) {
  await provider.getValues({ field, filters })
}
// after
for (const field of ['location_id']) { // Threads supports location_id only
  await provider.getValues({ field, filters })
}
Defensive patterns

Strategy: type-guard

Validate before calling

const THREADS_SUPPORTED_FIELDS = ['location_id'] as const
function threadsSupportsField(field: string): boolean {
  return (THREADS_SUPPORTED_FIELDS as readonly string[]).includes(field)
}

Type guard

function isThreadsOptionField(field: string): field is 'location_id' {
  return field === 'location_id'
}

Try / catch

try {
  await provider.getValues({ field, filters })
} catch (e) {
  if (e instanceof AppException && e.code === ResponseCode.ChannelPlatformOperationNotSupported) {
    return { values: [], supported: false } // skip unsupported field
  }
  throw e
}

Prevention

When it happens

Trigger: Calling getValues with input.field set to anything other than 'location_id' (e.g. 'topic_id', 'mentioned_user_id') for the Threads provider.

Common situations: Generic option-refresh UI iterating all registered filter fields for every platform and hitting Threads with fields it doesn't support; a newly added filter schema field without a corresponding getValues branch; client/platform mismatch after adding a shared field.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/210a501762b2303a. Report an issue: GitHub.