DynamoDb delete non-existent item does not fail, why?

It's possible to utilize ReturnValues to determine if delete did anything or not. If ReturnValues.Attributes is empty, it means delete didn't find a record to delete, and you can throw an error in this case. Example in JavaScript:

async function deleteWithThrowIfNotExists() {
  const dynamo = new AWS.DynamoDB.DocumentClient();
  const parameters = {
    Key: {
      user: 'john'
    },
    ReturnValues: 'ALL_OLD',
    TableName: 'users'
  };
  const response = await dynamo.delete(parameters).promise();
  if (!response.Attributes) {
    throw new Error('Cannot delete item that does not exist')
  }
}

It is by design:

Unless you specify conditions, the DeleteItem is an idempotent operation; running it multiple times on the same item or attribute does not result in an error response.

FROM: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html