Semântica de execução, restrições e segurança

Esta página resume como um Script se comporta em tempo de execução (ordem, transações, erros, bloqueio), a quais restrições estáticas ele está sujeito no momento de salvar e o seu modelo de segurança. Para a sintaxe, consulte o catálogo de Statements e as expressões de valor; para combinações práticas, consulte o cookbook.

Ordem de execução

  • Os statements são executados sequencialmente de cima para baixo. Ao alcançar um Return, a execução termina nesse ponto.
  • A execução acontece inline, no caminho que processa a requisição da chamada. A resposta da chamada é o próprio resultado da execução (para o formato da resposta, consulte Requisição e resposta na visão geral do Script), e o tempo concedido a uma execução é abordado abaixo em Orçamento de tempo.

Semântica de execução

Guard (pré-condições)

Não existe um Statement guard dedicado. Você o expressa com If e then:[Return]. Quando a condição é violada, retorna um resultado e não executa os Statements seguintes (um Script sem guard também é perfeitamente possível).

{ "type": "If", "condition": { "<": [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] },
  "then": [ { "type": "Return", "value": { "ok": false, "reason": "insufficient credit" }, "statusCode": 402 } ] }

Sem transações e compensação best-effort

Um Script não é uma transação. Em caso de falha, o engine tenta compensar (compensation) o trabalho realizado até então e retorna a causa do erro, mas com as seguintes limitações (assumidas por decisão de projeto).

  • Desfazer uma exclusão cria um novo sys.id, então as referências que apontavam para ele quebram.
  • Efeitos externos (Http) são irreversíveis (uma chamada que já foi feita, e a cobrança dela, não podem ser desfeitas).
  • A compensação pode simplesmente não ser executada, deixando um estado não compensado.

Se você precisa de atomicidade real, escreva a compensação no Script por conta própria ou coloque as operações irreversíveis (como chamadas externas) por último. A ordenação mais perigosa é aquela que "encadeia até o fim, mas não consegue reverter, e ainda assim parece segura".

Bloqueio otimista

Você reduz a contenção de update/patch com o version em ResourceUpdate e ResourcePatch. Se fornecer version (uma expressão de valor, Int), a atualização acontece somente quando coincide com o sys.version atual do alvo; uma divergência aborta com um erro de conflito de versão (que você pode tratar localmente com Try/catch). Se omitir, vale last-write-wins, sem verificação. Normalmente você lê primeiro com ResourceRead ou ResourceFind e passa esse sys.version (consulte CAS de bloqueio otimista no cookbook).

Gravações vão para origin

As gravações sempre chegam ao origin (draft), e a exposição na delivery (CDA/ACDA) é controlada por publish (o publish em ResourceCreate/ResourceUpdate/ResourcePatch, ou ResourcePublish/ResourceUnpublish).

O que conta como falha

Se um Statement falhar durante a execução, a execução é interrompida naquele ponto, a menos que haja um Try que trate essa falha. Quando isso acontece, o engine tenta desfazer o trabalho realizado até então. Desfazer tem limitações, e os detalhes são abordados em Sem transações e compensação best-effort.

Se o Statement que falhou estiver dentro de um Try, você pode tratar essa falha no catch. Dentro do catch, você referencia o conteúdo da falha ({ message }) via /error. Em qual Statement a falha ocorreu não é incluído.

Os casos a seguir são tratados como falha.

Um Return não é uma falha. Ele encerra a execução antecipadamente de forma normal, portanto não passa para o catch.

As duas formas de falha do Http

A falha de um Http divide-se em duas, conforme seja tratada ou não como uma resposta de status. Essa diferença determina se retry e ignoreStatusCode se aplicam.

TipoTratada como resposta de statusFalha imediata
CasosA API de destino responde com status 400 ou superior; o tempo se esgota (status 504); não foi possível conectar à API de destino ou ler a resposta (status 502); o corpo da resposta excede 10MiB (status 502)responseType é "Json", mas o corpo de uma resposta de sucesso não é JSON; o arquivo a enviar excede o limite de download; a URL do arquivo responde com um status que não é 2xx ou não é possível conectar à URL do arquivo; o formato do valor de uma part é inválido
retryTenta novamente o número de vezes especificadoNão tenta novamente
ignoreStatusCode: trueNão é considerada falha e vincula { status, body } como resultadoNão se aplica, e é tratada como falha
Try/catchPode ser tratada no catchPode ser tratada no catch

As condições de falha durante o envio de arquivos são abordadas em detalhe em Enviar um arquivo como corpo.

No servidor, apenas a contagem

A contagem é feita pelo ResourceCount no servidor. Como ele não traz os itens, não fica sujeito ao limite máximo de itens processados.

Para sum e group-by não há operações de servidor dedicadas. Essas agregações você precisa calcular por conta própria, percorrendo com ResourceForEach e usando SetVar e JsonLogic, portanto fica limitado pelo limite máximo de itens processados (inadequado para agregar milhões de registros). Se você precisa apenas da contagem, não percorra: use ResourceCount.

Sem espera ou atraso

Um Script não tem Statement Delay. Um Script é executado uma vez e pronto, e não espera nem faz polling internamente até um job externo terminar.

Restrições estáticas (validadas ao salvar)

Os itens a seguir são verificados no momento em que um Script é salvo (na criação/atualização). Se algum for violado, o salvamento é rejeitado (a falha ocorre no momento da autoria, não em tempo de execução). A seção Erros mostra qual violação é recusada com qual código.

RestriçãoValor
Máximo de chamadas externas por definição (Http, EmailSend)Por plano (veja Planos)
Máximo de itens processados por ResourceForEach (sem um limit declarado, percorre até este valor; falha se atingi-lo ainda havendo correspondências)10.000
Máximo de SetVar por definição (incluindo aninhados)10
Máximo de Cache por definição (incluindo aninhados, somados independentemente da operação)5. Acima disso, salvamento recusado
Cache dentro do bloco de um Loop, ResourceForEachSalvamento recusado
Cache.keySomente literal, no máximo 128 caracteres. Se for uma expressão de valor, salvamento recusado
Cache.ttlEntre 1 e 30 segundos; se omitido, 5. Fora disso, salvamento recusado
Máximo total de Statements por definição (incluindo aninhados)Por plano (veja Planos)
Limite de Http.retry2
Campos de corpo da requisição de um Http (body, urlBody, multipartBody)Apenas um dos três. Se escrever dois ou mais, salvamento recusado
Número de parts de Http.multipartBody1 ou mais. Se estiver vazio, salvamento recusado
value, url de uma part de multipartBodyExatamente um. Se escrever ambos ou deixar ambos vazios, salvamento recusado
fileName de uma part de multipartBodySomente na part que tem url. Se escrito sem url, salvamento recusado
Comprimento de Regex.pattern128 caracteres
Máximo de secrets por definição20
key de secrets1 a 64 caracteres, apenas letras, dígitos, _ e -. Se houver duas iguais, salvamento recusado
value de secrets1 a 4.096 caracteres. Fora disso, salvamento recusado
Referência { /secrets… }Exatamente /secrets/<key declarada>. Caso contrário, salvamento recusado
Statement que cria ou exclui um ServiceUserSalvamento recusado. Somente os três Statements de leitura e ResourceUpdate, ResourcePatch aceitam este recurso
Se anonymousCallEnabled for true, o createdBy: ":self" de whereSalvamento recusado
transformations de uma instrução de ingestão de Media (Transformação de arquivos)Somente array. O type dos elementos é PdfWatermark, e color é #RRGGBB. Em text, a string escrita inteira (incluindo os caminhos de { /pointer }) é uma única linha de caracteres permitidos. Caso contrário, salvamento recusado
Comprimento do text literal de PdfWatermark1 a 64 caracteres. Fora disso, salvamento recusado. Um text com { /pointer } não é verificado ao salvar, mas na execução, com o valor resolvido

Os limites fixos da tabela acima são valores definidos pela plataforma, portanto são os mesmos independentemente do plano. Já o número total de Statements e o número de chamadas externas por definição são limites por plano. Esses dois não são erros de validação, mas limites de plano; se ultrapassados, o salvamento e a edição são recusados por estouro do limite do plano (a mesma definição é permitida em um plano superior) e são liberados com um upgrade. Os valores por plano estão em Planos.

A ingestão de arquivo de Media, ao contrário de chamadas externas como Http, EmailSend, não entra no limite de chamadas externas por definição.

O ResourceForEach é um Statement composto que possui filhos, portanto ele próprio não conta no número de chamadas externas. Os Statements de chamada externa dentro de onEach (Http, EmailSend) é que são contados (estaticamente contam como 1, mas são de fato executados a cada item durante o percurso). Em onEach você pode incluir chamadas externas ou ingestão de arquivo de Media, e o mesmo vale para o body de Loop. Quantas voltas a iteração dá de fato não entra nessa contagem: em vez disso, ela entra como multiplicação no Orçamento de tempo abaixo.

Limites de comprimento de valor (tempo de execução)

Os Statements de assinatura e de tratamento de texto, e também o Cache, têm um limite máximo para o tamanho do valor que manipulam. Não é o comprimento da expressão, mas o comprimento do valor resolvido dessa expressão (os dezesseis caracteres de { /rawPayload } apontam para dezenas de KB), e é por isso que a verificação ocorre durante a execução, e não no momento do salvamento.

AlvoLimite máximoSe exceder
O value de Signature65.536 caracteresEsse Statement falha (status 422)
O value de Hash128 caracteresEsse Statement falha (status 422)
O value de Regex10.240 caracteres (10KiB)Esse Statement falha (status 400)
O value de Cache10.240 bytes (10KiB)Esse Statement falha (status 422)
  • Os quatro são iguais a qualquer outra falha em tempo de execução, portanto podem ser tratados localmente com Try/catch.
  • O limite máximo de Signature foi ajustado ao tamanho dos corpos que os provedores realmente enviam (um evento de pagamento tem alguns KB; um webhook de pedido chega a dezenas de KB). O de Hash é bem mais estreito, por ser a posição em que se concatenam alguns campos.
  • Os 128 caracteres de Regex.pattern são a verificação de salvamento que está nas Restrições estáticas acima. Esse comprimento não é um dispositivo para impedir explosões de custo ((a+)+$ já é perigoso com seis caracteres). O que impede a explosão é a regra que obriga o padrão a ser apenas literal, junto com o orçamento de tempo abaixo; o que o comprimento promete é somente um tamanho que uma pessoa consiga ler e revisar.

Orçamento de tempo (tempo de execução)

O tempo permitido para uma execução é de no máximo 180 segundos. O tempo efetivamente permitido é determinado pela definição do Script (e, quando se enviam arquivos, também pelo plano), e é o valor obtido somando aos 30 segundos base o tempo que as chamadas externas podem usar.

Esse orçamento se aplica à execução inteira. À parte disso, uma única requisição Http precisa terminar dentro do timeoutMs dessa requisição.

Base de 30 segundos

Todo trabalho que não é chamada externa, como ler e gravar recursos ou receber e processar arquivos de Media, é processado dentro desses 30 segundos. Um Script sem chamadas externas tem 30 segundos permitidos.

Tempo que cada Statement acrescenta

Os tempos dos Statements dispostos em sequência são todos somados.

StatementTempo somado
HttptimeoutMs (30 segundos, se não for especificado). Se enviar arquivos, soma o tempo de download de cada arquivo (tabela abaixo) e, se retry for especificado, multiplica o total pelo número de tentativas (1 + retry)
EmailSendtimeoutMs (10 segundos, se não for especificado). Como não tenta novamente, soma apenas uma vez
IfO tempo do mais longo entre then e else
ParallelO tempo do mais longo entre os branches
TryA soma dos tempos de body, catch e finally
LoopO tempo do body multiplicado por maxIterations (10.000, se não for especificado)
ResourceForEachO tempo do onEach multiplicado por limit (10.000, se não for especificado)
Os demais Statements (que não contêm outros Statements)Não somam. São processados dentro da base de 30 segundos

Se não houver chamadas externas dentro de uma iteração, o tempo somado é 0 mesmo multiplicado pelo número de iterações. Por isso, uma iteração assim precisa terminar dentro da base de 30 segundos.

Tempo de download por arquivo

PlanTempo de download
FreeCerca de 5,2 segundos
BasicCerca de 10,5 segundos
ProCerca de 10,5 segundos
EnterpriseCerca de 107,4 segundos

Esse valor é o tempo necessário para receber o limite de download do plano a 10.000.000 bytes por segundo.

Exemplo de cálculo

Um Script que chama um único Http que envia duas fotos (timeoutMs de 30 segundos, retry 1) no plano Pro é calculado da seguinte forma.

  • Http: (30 segundos + 10,5 segundos × 2) × 2 = cerca de 102 segundos
  • Execução inteira: 30 segundos + 102 segundos = cerca de 132 segundos

Como 132 segundos é menos que 180 segundos, este Script tem 132 segundos permitidos.

Quando ultrapassa 180 segundos

Mesmo que o valor calculado ultrapasse 180 segundos, o Script é salvo e executado. No entanto, quando a execução chega a 180 segundos, ela é interrompida naquele ponto.

Limites de quantidade por plano

Um Script tem a quantidade por Organization limitada por plano.

PlanQuantidade de Script
Free10
Basic30
Pro100
EnterpriseIlimitado

À parte disso, o número de Statements e o número de chamadas externas (Http, EmailSend) que uma definição de Script pode conter também são limitados por plano. Ao salvar ou editar uma definição, se ela ultrapassar o limite daquele plano, é recusada; para os valores concretos, consulte Planos.

Quando o limite é atingido, a criação de um novo Script é rejeitada.

Tamanho de download de arquivos do Http

Quando o Http busca em uma URL o arquivo a enviar como corpo da requisição (urlBody, a part url de multipartBody), o tamanho que pode ser recebido por URL de arquivo é limitado por plano. Vale o plano da Organization à qual pertence o Space dono daquele Script.

PlanTamanho máximo por URL de arquivo
Free50MiB
Basic100MiB
Pro100MiB
Enterprise1GiB
  • O limite se aplica separadamente a cada URL. Se houver várias parts url, cada arquivo precisa estar dentro desse limite.
  • Se você tentar enviar um arquivo que excede o limite, aquele Http falha (veja As duas formas de falha do Http).
  • Esse limite também é a base do tempo de download somado ao Orçamento de tempo.

Modelo de segurança

secrets

Valores secretos como chaves de APIs externas, chaves secretas de processadoras de pagamentos (PG), chaves de assinatura de webhook e valores de autenticação Basic … pré-calculados não são escritos literalmente em um Statement. Declare-os em secrets da definição e, no Statement, leia-os com { /secrets/<key> }. As chaves de teste públicas também ficam nesse mesmo lugar. Assim, ao trocar pela chave real, você deixa o Statement como está e altera apenas o valor em secrets.

"secrets": [
  { "key": "LLM_API_KEY",            "value": "sk-...",    "description": "Chave de API para chamar o LLM" },
  { "key": "WEBHOOK_SIGNING_SECRET", "value": "whsec_...", "description": "" }
],
"statements": [
  { "type": "Http", "method": "POST", "url": "https://api.openai.com/v1/chat/completions",
    "headers": [ { "key": "Authorization", "value": "Bearer { /secrets/LLM_API_KEY }" } ],
    "body": { /* ... */ }, "name": "llm" }
]
CampoObrigatórioRegra
keyObrigatórioDe 1 a 64 caracteres, usando apenas letras, dígitos, _ e -. Precisa ser única dentro de um Script.
valueObrigatórioUma string de 1 a 4.096 caracteres. Como é um valor estático, não é interpretado como template: mesmo que contenha { /… }, é usado literalmente.
descriptionObrigatórioA descrição do uso, de 0 a 128 caracteres. Uma string vazia "" também é aceita.
  • Armazenamento: a WEEGLOO criptografa o value e o armazena com segurança. O Statement lê o valor original com { /secrets/<key> }.
  • Consulta: nas respostas das APIs que devolvem o Script (consulta, criação e atualização), o value é retornado com o valor original. Como o valor fica visível para os papéis que podem ler aquele Script, mantenha estreita a permissão de leitura. Um membro (ServiceUser) não consegue ler a definição de um Script (a consulta e a autoria são exclusivas da CMA, e a ACMA não tem a API de Script).
  • Atualização: a atualização completa (PUT) substitui a definição inteira. Se você enviar sem secrets, os valores secretos declarados são apagados e, se um Statement ainda referenciar esses valores com { /secrets/… }, o salvamento é recusado. Por isso, envie secrets junto a cada atualização. Basta devolver os valores da resposta de consulta tal como vieram.
  • Valor durante a execução: o que fazer com o valor lido é decidido pelo Statement. Se você devolver o valor lido com Return, ele fica na resposta da execução e no ScriptLog; se colocá-lo em SetVar, Cache ou em um Content, ele fica ali com o valor original. Envie os valores secretos apenas para a API externa que precisa deles.
  • App Bundle: quando o Script é empacotado em um App Bundle, o value de secrets é mascarado como ******, e key e description vão como estão. Um Script criado pela instalação desse App Bundle fica com os valores secretos em ******; por isso, quem instala precisa inserir os valores reais para que os Statements que leem esses valores funcionem. Valores escritos fora de secrets (cabeçalhos de Http, o secret de Signature etc.) não são mascarados e vão como estão.

Um Script pode ter até 20 secrets. As regras do pointer são abordadas em /secrets em Expressões de valor.

Identidade de execução e autorização

  • Identidade de execução: durante a execução, toda operação de recurso é realizada sob a identidade do usuário que chamou /execute. O createdBy/updatedBy de qualquer recurso criado ou atualizado é o chamador, e um escopo createdBy: ":self" também é resolvido em relação ao chamador. A exceção é a chamada anônima. Uma execução que entra por /execute/anonymous não tem chamador, portanto ambos são resolvidos em relação ao autor (veja Chamada anônima).
  • Há dois limites de autorização e, em tempo de execução, o engine não reverifica as permissões de recurso a cada Statement.
    1. No momento da autoria (salvar): ao salvar um Script, verifica-se se o autor realmente possui as permissões de recurso e de ação que seus Statements usam. Se faltar uma que seja, o salvamento é rejeitado. Ou seja, um Script que contém uma operação não autorizada nunca chega a ser salvo. Todo Statement que seleciona um recurso passa por essa verificação, seja ele um leaf ou um ResourceForEach que possui um bloco. Uma definição já salva também é verificada de novo ao ser editada, portanto, depois que uma permissão é revogada, não é possível corrigir e salvar aquela definição.
      • O diretório de membros (ServiceUser) é verificado pelo eixo de configurações, não pelo mapa de permissões. Para usar resource: "ServiceUser" nos três Statements de leitura e em ResourceUpdate, ResourcePatch, o settings do SpaceRole do autor precisa ter SETTING_SERVICE_LOGIN (ou SETTING_ALL) (veja settings do SpaceRole). Isso porque o diretório de membros é, em todos os outros caminhos também, um recurso governado pelas configurações do Space.
      • Um Statement que cria ou exclui um membro não é salvo com nenhum papel. Como o Script não pode criar nem excluir um membro, a recusa não é por falta de permissão (403), mas por Statement escrito de forma inválida (400). Ou seja, não é uma lacuna que se feche acrescentando permissões. As únicas alterações permitidas são o roleOverride e o enableLogin de ResourceUpdate, ResourcePatch (veja Trabalhar com o diretório de membros).
    2. No momento da chamada (/execute): verifica-se apenas a permissão Execute do chamador sobre o Script. Sem ela, o resultado é 403. Uma vez aprovado, as permissões de recurso por Statement não são verificadas novamente em tempo de execução; a execução prossegue. Funciona como a permissão de execução de função na programação. Se você tem permissão para executar a função, a permissão de cada operação individual dentro dela não é perguntada de novo. No caminho de chamada anônima, essa verificação não existe. É porque não há chamador a verificar e, por isso, abrir aquele caminho equivale a publicar um Script sem autenticação.
  • Bloqueio de chamada direta (directCallEnabled): se o directCallEnabled de um Script for false, a própria chamada direta a /execute é rejeitada. Este gate é aplicado depois que a verificação da permissão Execute é aprovada, então ele bloqueia mesmo quem tem a permissão Execute. Um chamador sem essa permissão recebe 403 antes de chegar a este gate. Como esse gate existe apenas naquele endpoint, a ação de vínculo (script) de um Webhook e um Scheduler continuam executando o Script normalmente. O padrão é true (chamada direta permitida).
  • Chamada anônima (anonymousCallEnabled): o padrão é false. Se você deixá-lo como true, apenas aquele Script passa a ser executável também por um caminho dedicado e sem autenticação (/execute/anonymous), e nesse caso a identidade de execução é o autor, não o chamador. Dos dois limites acima, a verificação no momento da chamada (permissão Execute) não existe nesse caminho, portanto a autenticação efetiva é feita pelo próprio Script (verificando a assinatura da requisição recebida). As condições para ativá-lo e as regras de salvamento são abordadas em Chamada anônima.
  • Escopo de propriedade: createdBy: ":self" em um filtro where significa "apenas o que o chamador atual criou" (por exemplo, consultar apenas a própria carteira). Esse filtro não pode ser usado em um Script que permite chamada anônima. Como não há chamador e ele é resolvido para o autor, o sentido original de escopo de propriedade não se sustenta.
  • Permissões delegadas (atenção ao autor): combinando os dois limites acima, executar um Script equivale a agir com as permissões do autor delegadas a ele. O chamador precisa apenas de Execute, e os Statements dentro do Script são executados exatamente dentro do escopo para o qual o autor foi autorizado no momento de salvar. Como consequência, uma operação de recurso que o chamador não conseguiria realizar sozinho ainda pode acontecer por meio do Script. Como as permissões concedidas ao autor são o alcance efetivo desse Script, defina com cuidado quais ações você coloca em um Script.

Checklist de resumo

Antes de salvar, verifique o seguinte.

  • Se você ativou a chamada anônima (anonymousCallEnabled), não há createdBy: ":self" em where e você colocou no início o Statement que verifica a requisição recebida (Signature etc.).
  • O número de chamadas externas (Http, EmailSend) e o total de Statements estão dentro do limite do plano, SetVar é 10 ou menos e Cache é 5 ou menos.
  • Se você usou Cache, escreveu a key como literal e não a colocou dentro de um Loop ou de um ResourceForEach.
  • Se você percorrer um conjunto grande com ResourceForEach, declarou um limit ou verificou que o tamanho é conclusível.
  • Se você incluiu uma iteração (Loop, ResourceForEach), confirmou que ela entra como multiplicação no Orçamento de tempo (sem chamadas externas, o limite é o orçamento base de 30 segundos).
  • Valores secretos como chaves de APIs externas ou chaves de assinatura foram declarados em secrets e lidos com { /secrets/<key> }. Não há nenhum valor secreto escrito literalmente em um Statement.
  • Se você salva com uma atualização completa (PUT), enviou secrets junto.
  • A mensagem usada na verificação de assinatura foi tomada de { /rawPayload }, e não de /payload.
  • Se houver um Statement que trabalha com um membro (ServiceUser), o autor tem SETTING_SERVICE_LOGIN e você não incluiu nenhum Statement que crie ou exclua esse recurso.
  • As operações irreversíveis (chamadas externas) foram colocadas o mais tarde possível.
  • Se você envia arquivos com Http, escreveu apenas um campo de corpo da requisição (body, urlBody, multipartBody) e verificou que cada arquivo está dentro do limite de download por plano.
  • Se você se preocupa com a contenção de update/patch, use o version em ResourceUpdate ou ResourcePatch.
  • Para retornar um resultado, você especificou Return.value.

Erros

São os códigos que aparecem quando o salvamento é recusado porque a forma da definição viola uma restrição estática. Os códigos que violam as regras das expressões de valor estão em Erros em Expressões de valor, e os que aparecem na chamada e na exclusão, em Erros em Recurso e endpoints do Script. Para os códigos comuns a todos os recursos, consulte Erros comuns.

CódigoCondição
WGL400066A definição contém mais de 5 Statements Cache.
WGL400068A definição coloca um Statement Cache dentro do bloco de um Loop ou de um ResourceForEach.
WGL400067A key de um Statement Cache traz uma referência { /pointer } em vez de um literal.
WGL400065O ttl de um Statement Cache está fora da faixa permitida.
WGL400063Um Statement Cache traz um campo que não corresponde ao seu action (ttl em um Get, defaultValue em um Set).
WGL400060ResourceCreate, ResourceDelete ou um Statement de publicação ou arquivamento traz "ServiceUser" em resource. O diretório de membros é aceito apenas pelos três Statements de consulta e por ResourceUpdate, ResourcePatch.
WGL400077O resource de um ResourceCount traz um recurso que não pode ser contado. Media e o diretório de membros (ServiceUser) não podem ser contados.
WGL400037Um EmailSend traz to e toServiceUser juntos, ou deixou os dois vazios. Escreva exatamente um deles.
WGL400054O total de destinatários de um EmailSend (to 1 + cc + bcc) passa de 50.
WGL400039O timeoutMs de um EmailSend passa do limite máximo.
WGL400101Um EmailSend traz body e templateBody juntos, ou deixou os dois vazios. Escreva exatamente um deles.
WGL400102O templateBody.source de um EmailSend não é um único ponteiro que aponta para um Content lido pelo ResourceRead, ResourceFind deste Script. Também é recusado se houver outros caracteres antes ou depois do ponteiro.
WGL400061Em um Script que permite chamada anônima (anonymousCallEnabled), um Statement de leitura traz createdBy: ":self" em where.
WGL400023A definição contém mais de 10 Statements SetVar.
WGL400026O retry de um Statement Http ultrapassa o limite máximo de 2.
WGL400087Um Http traz dois ou mais campos de corpo da requisição (body, urlBody, multipartBody).
WGL400088O multipartBody de um Http não tem nenhuma part.
WGL400089Uma part de multipartBody traz value e url juntos, ou não traz nenhum dos dois.
WGL400090Uma part de multipartBody traz fileName sem url.
WGL400036O ResourceForEach ultrapassa o limite máximo de itens que ele pode processar.
WGL400094Há dois ou mais itens em secrets que usam a mesma key.
WGL400095A definição contém mais de 20 secrets.
WGL400086O value de secrets está fora da faixa de 1 a 4.096 caracteres. O erro não traz o value.
WGL400086O text de um PdfWatermark sem { /pointer } está fora da faixa de 1 a 64 caracteres.
WGL400096Em uma instrução de ingestão de Media, transformations não é um array, o type de um elemento não é PdfWatermark, um PdfWatermark não tem text ou o tem como objeto ou array, color não está no formato #RRGGBB, ou o text tal como foi escrito contém caracteres não permitidos ou quebras de linha.
WGL429005O número total de Statements que a definição contém ultrapassa o limite do plano.
WGL429006O número de chamadas externas (Http, EmailSend) que a definição contém ultrapassa o limite do plano.
WGL403015O autor não possui as permissões de recurso e de ação que os Statements da definição usam. Mesmo que ele tenha a permissão, o salvamento é recusado se essa autorização vier com um filtro contentType, createdBy ou tag. A autorização precisa ser incondicional. A única exceção é o Create de Content, para o qual também vale uma autorização com escopo de contentType, que é comparada com o contentType escrito no Statement (o Create de Media não tem essa exceção). Um Statement de leitura que traz "ServiceUser" em resource quando o autor não tem SETTING_SERVICE_LOGIN também recebe este código.