{"record":{"id":"1b499ff8e529b575","repo":"yikart/AiToEarn","slug":"channelplatformoperationnotsupported-1b499f","errorCode":"ChannelPlatformOperationNotSupported","errorMessage":"ChannelPlatformOperationNotSupported","messagePattern":"ChannelPlatformOperationNotSupported","errorType":"error_code","errorClass":"AppException","httpStatus":null,"severity":"error","filePath":"project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/platforms.service.ts","lineNumber":68,"sourceCode":"      filters: parsedFilters,\n      credential: {\n        accessToken: credential.accessToken,\n        refreshToken: credential.refreshToken,\n        platformUid: account.uid,\n        account: account.account,\n      },\n    }))\n  }\n\n  async createAccountValue(\n    userId: string,\n    accountId: string,\n    field: string,\n    data?: object,\n  ): Promise<PublishOptionCreateResult> {\n    const { account, provider, source } = await this.getAccountOptionContext(userId, accountId, field)\n    if (!provider.createValue || !source.createSchema) {\n      throw new AppException(ResponseCode.ChannelPlatformOperationNotSupported, {\n        platform: account.type,\n        field,\n      })\n    }\n\n    const parsedData = source.createSchema.parse(data ?? {}) as Record<string, unknown>\n    const credential = await this.authService.getValidCredential(accountId, userId)\n    return this.callAccountProvider(accountId, () => provider.createValue!({\n      userId,\n      accountId,\n      field,\n      data: parsedData,\n      credential: {\n        accessToken: credential.accessToken,\n        refreshToken: credential.refreshToken,\n        platformUid: account.uid,\n        account: account.account,\n      },","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/platforms.service.ts#L50-L86","documentation":"createAccountValue handles dynamic 'publish option' fields (custom create-value sources, e.g. creating a board/list on the platform). After resolving { account, provider, source } via getAccountOptionContext, if the resolved provider has no createValue implementation or the source has no createSchema, the field is list-only and cannot have values created, so it throws ChannelPlatformOperationNotSupported with the platform and field.","triggerScenarios":"POSTing to the create-account-value endpoint (userId, accountId, field, data) where `field` names an option source that only supports listing (provider.createValue undefined or source.createSchema undefined) — e.g. trying to 'create' a value for a read-only dropdown like a fixed category list.","commonSituations":"A UI that renders a generic '+ add new' button next to every option field; clients guessing the create endpoint works for all fields; schema changed so createSchema was dropped while the client still calls create.","solutions":["Consult the field's option source metadata (whether create is offered, e.g. via optionSchema / source capabilities) and hide the create action for list-only fields.","Use the list endpoint (values from listSources/list values) instead of the create endpoint for fields without create support.","If creation should be supported, implement provider.createValue and define source.createSchema in the platform integration.","Map this response code in the client to a per-field 'operation not available' message rather than a global error."],"exampleFix":"// before\nawait api.post(`/accounts/${accountId}/options/${field}/values`, data) // may 400\n// after\nif (!fieldMeta.canCreate) {\n  throw new BadRequestException(`Field ${field} does not support creating values`)\n}\nawait api.post(`/accounts/${accountId}/options/${field}/values`, data)","handlingStrategy":"validation","validationCode":"const source = optionSources.find(s => s.field === field)\nif (!source?.canCreate) { // no createValue / createSchema\n  throw new BadRequestException(`Field ${field} is read-only`)\n}","typeGuard":"function isCreatableSource(source: PublishOptionSource): source is PublishOptionSource & { createSchema: z.ZodTypeAny } {\n  return Boolean(source.createSchema)\n}","tryCatchPattern":"try {\n  await api.createAccountValue(accountId, field, data)\n} catch (e) {\n  if (e instanceof AppException && e.code === ResponseCode.ChannelPlatformOperationNotSupported) {\n    showError(`Cannot create values for ${e.details.field} on ${e.details.platform}`)\n    return\n  }\n  throw e\n}","preventionTips":["Render the '+ add' button only for fields whose source supports creation.","Derive field capabilities from the platform's option source metadata, not assumptions.","Handle per-field errors distinctly in publish forms.","Keep createValue and createSchema in sync when editing integrations."],"tags":["publish-options","platform-capability","unsupported-operation"],"backgroundTag":"platform-operation-not-supported","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}