Open Yancey1989 opened 4 years ago
There're many other errors about attribute checking or other semantics checking:
SELECT * from iris.train TO TRAIN DNNClassifier WITH model.hidden_units=x LABEL class INTO iris.xgb;
What we have:
Traceback (most recent call last):
File "<stdin>", line 136, in <module>
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/tensorflow/train.py", line 126, in train
save_checkpoints_steps, validation_metrics)
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/tensorflow/train_estimator.py", line 65, in estimator_train_and_save
eval_start_delay_secs, eval_throttle_secs)
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/tensorflow/train_estimator.py", line 105, in estimator_train_compiled
estimator.train(lambda: train_dataset_fn(), max_steps=train_max_steps)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/estimator.py", line 370, in train
loss = self._train_model(input_fn, hooks, saving_listeners)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/estimator.py", line 1160, in _train_model
return self._train_model_default(input_fn, hooks, saving_listeners)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/estimator.py", line 1190, in _train_model_default
features, labels, ModeKeys.TRAIN, self.config)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/estimator.py", line 1148, in _call_model_fn
model_fn_results = self._model_fn(features=features, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/canned/dnn.py", line 764, in _model_fn
batch_norm=batch_norm)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/canned/dnn.py", line 573, in dnn_model_fn_v2
mode=mode)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/canned/dnn.py", line 508, in _dnn_model_fn_builder_v2
name='dnn')
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/canned/dnn.py", line 328, in __init__
name=hidden_shared_name)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/layers/core.py", line 995, in __init__
self.units = int(units)
ValueError: invalid literal for int() with base 10: 'x'
ERROR: rpc error: code = Unknown desc = runSQLProgram error: failed: exit status 1
==========Program==========
import copy
import tensorflow as tf
from sqlflow_submitter.tensorflow.train import train
from sqlflow_submitter.tensorflow.get_tf_version import tf_is_version2
from tensorflow.estimator import (DNNClassifier,
DNNRegressor,
LinearClassifier,
LinearRegressor,
BoostedTreesClassifier,
BoostedTreesRegressor,
DNNLinearCombinedClassifier,
DNNLinearCombinedRegressor)
if tf_is_version2():
from tensorflow.keras.optimizers import Adadelta, Adagrad, Adam, Adamax, Ftrl, Nadam, RMSprop, SGD
from tensorflow.keras.losses import BinaryCrossentropy, CategoricalCrossentropy, CategoricalHinge, CosineSimilarity, Hinge, Huber, KLDivergence, LogCosh, MeanAbsoluteError, MeanAbsolutePercentageError, MeanSquaredError, MeanSquaredLogarithmicError, Poisson, SparseCategoricalCrossentropy, SquaredHinge
else:
from tensorflow.train import AdadeltaOptimizer, AdagradOptimizer, AdamOptimizer, FtrlOptimizer, RMSPropOptimizer, GradientDescentOptimizer, MomentumOptimizer
from tensorflow.keras.losses import BinaryCrossentropy, CategoricalCrossentropy, CategoricalHinge, CosineSimilarity, Hinge, Huber, KLDivergence, LogCosh, MeanAbsoluteError, MeanAbsolutePercentageError, MeanSquaredError, MeanSquaredLogarithmicError, Poisson, SparseCategoricalCrossentropy, SquaredHinge
try:
import sqlflow_models
except Exception as e:
print("failed to import sqlflow_models: %s", e)
feature_column_names = [
"sepal_length",
"sepal_width",
"petal_length",
"petal_width",
]
# feature_column_names_map is used to determine the order of feature columns of each target:
# e.g. when using DNNLinearCombinedClassifer.
# feature_column_names_map will be saved to a single file when using PAI.
feature_column_names_map = dict()
feature_column_names_map["feature_columns"] = ["sepal_length","sepal_width","petal_length","petal_width",]
feature_metas = dict()
feature_metas["sepal_length"] = {
"feature_name": "sepal_length",
"dtype": "float32",
"delimiter": "",
"shape": [1],
"is_sparse": "false" == "true"
}
feature_metas["sepal_width"] = {
"feature_name": "sepal_width",
"dtype": "float32",
"delimiter": "",
"shape": [1],
"is_sparse": "false" == "true"
}
feature_metas["petal_length"] = {
"feature_name": "petal_length",
"dtype": "float32",
"delimiter": "",
"shape": [1],
"is_sparse": "false" == "true"
}
feature_metas["petal_width"] = {
"feature_name": "petal_width",
"dtype": "float32",
"delimiter": "",
"shape": [1],
"is_sparse": "false" == "true"
}
label_meta = {
"feature_name": "class",
"dtype": "int64",
"delimiter": "",
"shape": [],
"is_sparse": "false" == "true"
}
model_params=dict()
model_params["hidden_units"]="x"
# Construct optimizer objects to pass to model initializer.
# The original model_params is serializable (do not have tf.xxx objects).
model_params_constructed = copy.deepcopy(model_params)
for optimizer_arg in ["optimizer", "dnn_optimizer", "linear_optimizer"]:
if optimizer_arg in model_params_constructed:
model_params_constructed[optimizer_arg] = eval(model_params_constructed[optimizer_arg])
if "loss" in model_params_constructed:
model_params_constructed["loss"] = eval(model_params_constructed["loss"])
# feature_columns_code will be used to save the training informations together
# with the saved model.
feature_columns_code = """{"feature_columns": [tf.feature_column.numeric_column("sepal_length", shape=[1]),
tf.feature_column.numeric_column("sepal_width", shape=[1]),
tf.feature_column.numeric_column("petal_length", shape=[1]),
tf.feature_column.numeric_column("petal_width", shape=[1])]}"""
feature_columns = eval(feature_columns_code)
train_max_steps = 0
train_max_steps = None if train_max_steps == 0 else train_max_steps
train(datasource="mysql://root:root@tcp(127.0.0.1:3306)/?maxAllowedPacket=0",
estimator=DNNClassifier,
select="""SELECT * from iris.train """,
validation_select="""""",
feature_columns=feature_columns,
feature_column_names=feature_column_names,
feature_metas=feature_metas,
label_meta=label_meta,
model_params=model_params_constructed,
validation_metrics="Accuracy".split(","),
save="model_save",
batch_size=1,
epoch=1,
validation_steps=1,
verbose=0,
max_steps=train_max_steps,
validation_start_delay_secs=0,
validation_throttle_secs=0,
save_checkpoints_steps=100,
log_every_n_iter=10,
is_pai="false" == "true",
pai_table="",
pai_val_table="")
==========Output==========
Start training using estimator model...
Traceback (most recent call last):
File "<stdin>", line 136, in <module>
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/tensorflow/train.py", line 126, in train
save_checkpoints_steps, validation_metrics)
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/tensorflow/train_estimator.py", line 65, in estimator_train_and_save
eval_start_delay_secs, eval_throttle_secs)
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/tensorflow/train_estimator.py", line 105, in estimator_train_compiled
estimator.train(lambda: train_dataset_fn(), max_steps=train_max_steps)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/estimator.py", line 370, in train
loss = self._train_model(input_fn, hooks, saving_listeners)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/estimator.py", line 1160, in _train_model
return self._train_model_default(input_fn, hooks, saving_listeners)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/estimator.py", line 1190, in _train_model_default
features, labels, ModeKeys.TRAIN, self.config)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/estimator.py", line 1148, in _call_model_fn
model_fn_results = self._model_fn(features=features, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/canned/dnn.py", line 764, in _model_fn
batch_norm=batch_norm)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/canned/dnn.py", line 573, in dnn_model_fn_v2
mode=mode)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/canned/dnn.py", line 508, in _dnn_model_fn_builder_v2
name='dnn')
File "/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/python/estimator/canned/dnn.py", line 328, in __init__
name=hidden_shared_name)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/layers/core.py", line 995, in __init__
self.units = int(units)
ValueError: invalid literal for int() with base 10: 'x'
What we want:
error: invalid attribute type: hidden_units of DNNClassifier should be an integer list like [30, 20, 10]
SELECT * from iris.train TO TRAIN DNNClassifier WITH model.n_classes=3 LABEL class INTO iris.xgb;
What we have is
Traceback (most recent call last):
File "<stdin>", line 136, in <module>
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/tensorflow/train.py", line 126, in train
save_checkpoints_steps, validation_metrics)
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/tensorflow/train_estimator.py", line 54, in estimator_train_and_save
classifier = estimator(**model_params)
TypeError: __init__() missing 1 required positional argument: 'hidden_units'
ERROR: rpc error: code = Unknown desc = runSQLProgram error: failed: exit status 1
==========Program==========
import copy
import tensorflow as tf
from sqlflow_submitter.tensorflow.train import train
from sqlflow_submitter.tensorflow.get_tf_version import tf_is_version2
from tensorflow.estimator import (DNNClassifier,
DNNRegressor,
LinearClassifier,
LinearRegressor,
BoostedTreesClassifier,
BoostedTreesRegressor,
DNNLinearCombinedClassifier,
DNNLinearCombinedRegressor)
if tf_is_version2():
from tensorflow.keras.optimizers import Adadelta, Adagrad, Adam, Adamax, Ftrl, Nadam, RMSprop, SGD
from tensorflow.keras.losses import BinaryCrossentropy, CategoricalCrossentropy, CategoricalHinge, CosineSimilarity, Hinge, Huber, KLDivergence, LogCosh, MeanAbsoluteError, MeanAbsolutePercentageError, MeanSquaredError, MeanSquaredLogarithmicError, Poisson, SparseCategoricalCrossentropy, SquaredHinge
else:
from tensorflow.train import AdadeltaOptimizer, AdagradOptimizer, AdamOptimizer, FtrlOptimizer, RMSPropOptimizer, GradientDescentOptimizer, MomentumOptimizer
from tensorflow.keras.losses import BinaryCrossentropy, CategoricalCrossentropy, CategoricalHinge, CosineSimilarity, Hinge, Huber, KLDivergence, LogCosh, MeanAbsoluteError, MeanAbsolutePercentageError, MeanSquaredError, MeanSquaredLogarithmicError, Poisson, SparseCategoricalCrossentropy, SquaredHinge
try:
import sqlflow_models
except Exception as e:
print("failed to import sqlflow_models: %s", e)
feature_column_names = [
"sepal_length",
"sepal_width",
"petal_length",
"petal_width",
]
# feature_column_names_map is used to determine the order of feature columns of each target:
# e.g. when using DNNLinearCombinedClassifer.
# feature_column_names_map will be saved to a single file when using PAI.
feature_column_names_map = dict()
feature_column_names_map["feature_columns"] = ["sepal_length","sepal_width","petal_length","petal_width",]
feature_metas = dict()
feature_metas["sepal_length"] = {
"feature_name": "sepal_length",
"dtype": "float32",
"delimiter": "",
"shape": [1],
"is_sparse": "false" == "true"
}
feature_metas["sepal_width"] = {
"feature_name": "sepal_width",
"dtype": "float32",
"delimiter": "",
"shape": [1],
"is_sparse": "false" == "true"
}
feature_metas["petal_length"] = {
"feature_name": "petal_length",
"dtype": "float32",
"delimiter": "",
"shape": [1],
"is_sparse": "false" == "true"
}
feature_metas["petal_width"] = {
"feature_name": "petal_width",
"dtype": "float32",
"delimiter": "",
"shape": [1],
"is_sparse": "false" == "true"
}
label_meta = {
"feature_name": "class",
"dtype": "int64",
"delimiter": "",
"shape": [],
"is_sparse": "false" == "true"
}
model_params=dict()
model_params["n_classes"]=3
# Construct optimizer objects to pass to model initializer.
# The original model_params is serializable (do not have tf.xxx objects).
model_params_constructed = copy.deepcopy(model_params)
for optimizer_arg in ["optimizer", "dnn_optimizer", "linear_optimizer"]:
if optimizer_arg in model_params_constructed:
model_params_constructed[optimizer_arg] = eval(model_params_constructed[optimizer_arg])
if "loss" in model_params_constructed:
model_params_constructed["loss"] = eval(model_params_constructed["loss"])
# feature_columns_code will be used to save the training informations together
# with the saved model.
feature_columns_code = """{"feature_columns": [tf.feature_column.numeric_column("sepal_length", shape=[1]),
tf.feature_column.numeric_column("sepal_width", shape=[1]),
tf.feature_column.numeric_column("petal_length", shape=[1]),
tf.feature_column.numeric_column("petal_width", shape=[1])]}"""
feature_columns = eval(feature_columns_code)
train_max_steps = 0
train_max_steps = None if train_max_steps == 0 else train_max_steps
train(datasource="mysql://root:root@tcp(127.0.0.1:3306)/?maxAllowedPacket=0",
estimator=DNNClassifier,
select="""SELECT * from iris.train """,
validation_select="""""",
feature_columns=feature_columns,
feature_column_names=feature_column_names,
feature_metas=feature_metas,
label_meta=label_meta,
model_params=model_params_constructed,
validation_metrics="Accuracy".split(","),
save="model_save",
batch_size=1,
epoch=1,
validation_steps=1,
verbose=0,
max_steps=train_max_steps,
validation_start_delay_secs=0,
validation_throttle_secs=0,
save_checkpoints_steps=100,
log_every_n_iter=10,
is_pai="false" == "true",
pai_table="",
pai_val_table="")
==========Output==========
Start training using estimator model...
Traceback (most recent call last):
File "<stdin>", line 136, in <module>
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/tensorflow/train.py", line 126, in train
save_checkpoints_steps, validation_metrics)
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/tensorflow/train_estimator.py", line 54, in estimator_train_and_save
classifier = estimator(**model_params)
TypeError: __init__() missing 1 required positional argument: 'hidden_units'
What we want is
error: required argument missed: hidden_units of DNNClassifier must be provided
SELECT * from iris.train TO TRAIN DNNClassifier WITH model.n_classes=3 LABEL asdf INTO iris.xgb ;
SELECT asdf from iris.train TO TRAIN DNNClassifier WITH model.n_classes=3 LABEL asdf INTO iris.xgb;
What we have
ERROR: rpc error: code = Unknown desc = runSQLProgram error: deriveLabel: LABEL COLUMN 'asdf' not found
ERROR: rpc error: code = Unknown desc = runSQLProgram error: Error 1054: Unknown column 'asdf' in 'field list'
What we want
error: unknown column: 'asdf' in 'field list' not found in 'iris.train'
error: unknown column: 'asdf' in 'label list' not found in 'iris.train'
SELECT * from iris.train TO TRAIN xgboost.gbtree WITH objective=multi:softmax INTO iris.xgb;
What we have
Traceback (most recent call last):
File "<stdin>", line 35, in <module>
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/xgboost/train.py", line 53, in train
for per_batch_dmatrix in dtrain:
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/xgboost/dataset.py", line 60, in xgb_dataset
feature_specs, label_spec)
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/xgboost/dataset.py", line 96, in dump_dmatrix
row_data = [str(item[1])] + row_data
IndexError: tuple index out of range
ERROR: rpc error: code = Unknown desc = runSQLProgram error: failed: exit status 1
==========Program==========
from sqlflow_submitter.xgboost.train import train
import json
model_params = json.loads('''{"booster":"gbtree","eta":0.3,"objective":"multi:softmax","validation.select":""}''')
train_params = json.loads('''{"num_boost_round":10}''')
feature_metas = json.loads('''{"class":{"feature_name":"class","dtype":"int64","delimiter":"","shape":[1],"is_sparse":false},"petal_length":{"feature_name":"petal_length","dtype":"float32","delimiter":"","shape":[1],"is_sparse":false},"petal_width":{"feature_name":"petal_width","dtype":"float32","delimiter":"","shape":[1],"is_sparse":false},"sepal_length":{"feature_name":"sepal_length","dtype":"float32","delimiter":"","shape":[1],"is_sparse":false},"sepal_width":{"feature_name":"sepal_width","dtype":"float32","delimiter":"","shape":[1],"is_sparse":false}}''')
label_meta = json.loads('''{"feature_name":"","dtype":"int64","delimiter":"","shape":null,"is_sparse":false}''')
feature_column_names = [
"sepal_length",
"sepal_width",
"petal_length",
"petal_width",
"class",
]
train(datasource='''mysql://root:root@tcp(127.0.0.1:3306)/?maxAllowedPacket=0''',
select='''SELECT * from iris.train ''',
model_params=model_params,
train_params=train_params,
feature_metas=feature_metas,
feature_column_names=feature_column_names,
label_meta=label_meta,
validation_select='''''',
disk_cache="false" == "true",
batch_size=-1,
epoch=1,
is_pai="false" == "true",
pai_train_table="",
pai_validate_table="")
==========Output==========
Start training XGBoost model...
Traceback (most recent call last):
File "<stdin>", line 35, in <module>
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/xgboost/train.py", line 53, in train
for per_batch_dmatrix in dtrain:
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/xgboost/dataset.py", line 60, in xgb_dataset
feature_specs, label_spec)
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/xgboost/dataset.py", line 96, in dump_dmatrix
row_data = [str(item[1])] + row_data
IndexError: tuple index out of range
What we want
error: 'xgboost.gbtree' is a supervised model, but LABEL clause is not provided.
SELECT * from iris.train TO TRAIN xgboost.gbtree WITH objective=multi:softmax LABEL class INTO iris.xgb;
What we have:
Traceback (most recent call last):
File "<stdin>", line 33, in <module>
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/xgboost/train.py", line 64, in train
**train_params)
File "/usr/local/lib/python3.6/dist-packages/xgboost/training.py", line 216, in train
xgb_model=xgb_model, callbacks=callbacks)
File "/usr/local/lib/python3.6/dist-packages/xgboost/training.py", line 74, in _train_internal
bst.update(dtrain, i, obj)
File "/usr/local/lib/python3.6/dist-packages/xgboost/core.py", line 1109, in update
dtrain.handle))
File "/usr/local/lib/python3.6/dist-packages/xgboost/core.py", line 176, in _check_call
raise XGBoostError(py_str(_LIB.XGBGetLastError()))
xgboost.core.XGBoostError: value 0 for Parameter num_class should be greater equal to 1
ERROR: rpc error: code = Unknown desc = runSQLProgram error: failed: exit status 1
==========Program==========
from sqlflow_submitter.xgboost.train import train
import json
model_params = json.loads('''{"booster":"gbtree","eta":0.3,"objective":"multi:softmax","validation.select":""}''')
train_params = json.loads('''{"num_boost_round":10}''')
feature_metas = json.loads('''{"petal_length":{"feature_name":"petal_length","dtype":"float32","delimiter":"","shape":[1],"is_sparse":false},"petal_width":{"feature_name":"petal_width","dtype":"float32","delimiter":"","shape":[1],"is_sparse":false},"sepal_length":{"feature_name":"sepal_length","dtype":"float32","delimiter":"","shape":[1],"is_sparse":false},"sepal_width":{"feature_name":"sepal_width","dtype":"float32","delimiter":"","shape":[1],"is_sparse":false}}''')
label_meta = json.loads('''{"feature_name":"class","dtype":"int64","delimiter":"","shape":[],"is_sparse":false}''')
feature_column_names = [
"sepal_length",
"sepal_width",
"petal_length",
"petal_width",
]
train(datasource='''mysql://root:root@tcp(127.0.0.1:3306)/?maxAllowedPacket=0''',
select='''SELECT * from iris.train ''',
model_params=model_params,
train_params=train_params,
feature_metas=feature_metas,
feature_column_names=feature_column_names,
label_meta=label_meta,
validation_select='''''',
disk_cache="false" == "true",
batch_size=-1,
epoch=1,
is_pai="false" == "true",
pai_train_table="",
pai_validate_table="")
==========Output==========
Start training XGBoost model...
[12:39:48] 110x4 matrix with 440 entries loaded from train.txt_0
Traceback (most recent call last):
File "<stdin>", line 33, in <module>
File "/root/go/src/sqlflow.org/sqlflow/python/sqlflow_submitter/xgboost/train.py", line 64, in train
**train_params)
File "/usr/local/lib/python3.6/dist-packages/xgboost/training.py", line 216, in train
xgb_model=xgb_model, callbacks=callbacks)
File "/usr/local/lib/python3.6/dist-packages/xgboost/training.py", line 74, in _train_internal
bst.update(dtrain, i, obj)
File "/usr/local/lib/python3.6/dist-packages/xgboost/core.py", line 1109, in update
dtrain.handle))
File "/usr/local/lib/python3.6/dist-packages/xgboost/core.py", line 176, in _check_call
raise XGBoostError(py_str(_LIB.XGBGetLastError()))
xgboost.core.XGBoostError: value 0 for Parameter num_class should be greater equal to 1
What we want:
error: invalid argument: num_class of xgboost.gbtree should be greater or equal to 1
Came from @llxxxll
SELECT * from fake.train TO TRAIN xgboost.gbtree
WITH objective=multi:softmax
INTO fake.xgb;
XGboost's feature type should be numerical if some column type of fake.train
is string, .e.g. cat
, dog
, we should tell users it does work on string feature column type.
What we have: TBD
What we want:
column type error: data type of input feature column `f` should be numerical for xgboost.gbtree estimator.
@Yancey1989 and @shendiaomo , thank you so much for the summarization of these error reporting. We definitely need to do something to make it better. Here follow my few cents.
In my mind, I have the following error handling schema in Go code.
panic
and recover
unless justifiable; instead,Given these two points, we can have error handling like shown in the following code snippet.
func a_func(params Something) (SomethingElse, error) {
if e := do_some_thing(); e != nil {
return nil, fmt.Errorf("a_func: waited to do .... but cannot do some thing:\n%v", e)
}
return result, nil
}
func grpc_server_Run() (Response, error) {
r, e := a_func()
if e != nil {
return nil, fmt.Errorf("grpc_server_Run: wanted to ... but ...:\n%v", e)
}
}
func grpc_client_main() {
r, e := stub.Call(a_func)
if e != nil {
log.Error(e)
}
}
SQLFlow Error Message Examples
This issue sorting some error cases according to the following bullets:
DataBase Connection Error
This error can occur on any SQL
Error Messages:
What we want:
PAI submitter program runtime error
What we want:
Syntax Error
Error Message:
What we want:
Attribute Check Error
Error Message:
What we want: